<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>werbos</title><link>/</link><description>Recent content on werbos</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Thu, 15 Oct 2026 21:30:00 -0700</lastBuildDate><atom:link href="/index.xml" rel="self" type="application/rss+xml"/><item><title>★ Current model — talk base · v3 book-pretrained 336M</title><link>/benchmarks/current-model/</link><pubDate>Wed, 02 Sep 2026 16:40:00 -0700</pubDate><guid>/benchmarks/current-model/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>The pinned card.&lt;/strong> Not a writeup — a &lt;em>live status&lt;/em>. How big is the model, how well did it learn, is it deployed, and can you trust it. Updated every version.&lt;/p>&lt;/blockquote>
&lt;h2 id="-temperature">🌡️ Temperature&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Model&lt;/strong>&lt;/td>
 &lt;td>&lt;code>talk-336m&lt;/code> (book-pretrained base — the current &lt;code>current&lt;/code> pointer on SR8)&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Version&lt;/strong>&lt;/td>
 &lt;td>&lt;strong>v3 · book-pretrained champion&lt;/strong> &lt;em>(B.20, 2026-08-24)&lt;/em>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Deployed&lt;/strong>&lt;/td>
 &lt;td>✅ live on SR8 — &lt;code>current&lt;/code> → &lt;code>talk-336m&lt;/code>, serving the chat owned-talk phase + the mind&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Actual size&lt;/strong>&lt;/td>
 &lt;td>&lt;strong>336M&lt;/strong> parameters &lt;em>(a real jump from the July 15M v2 — and the first time scale didn&amp;rsquo;t hurt)&lt;/em>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Corpus&lt;/strong>&lt;/td>
 &lt;td>book-pretrained &lt;strong>4.92B tokens&lt;/strong> (14.63 tok/param, 32k BPE, EOT) → fine-tuned &lt;strong>16,880 steps&lt;/strong> on &lt;strong>377,700&lt;/strong> conversation pairs&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Held-out loss&lt;/strong>&lt;/td>
 &lt;td>&lt;strong>3.184&lt;/strong> &lt;em>(32k-BPE chat held-out — &lt;strong>not comparable&lt;/strong> to v2&amp;rsquo;s 2.29; different tokenizer and corpus)&lt;/em>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>talk_bench floors&lt;/strong>&lt;/td>
 &lt;td>clean &lt;strong>1.00&lt;/strong> · input-sensitive &lt;strong>0.96&lt;/strong> · adjacency &lt;strong>0.92&lt;/strong> · stable &lt;strong>1.00&lt;/strong> · ood &lt;strong>0.00&lt;/strong>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Tongue gauntlet (before)&lt;/strong>&lt;/td>
 &lt;td>fluency &lt;strong>&amp;gt; llama3.2:3b&lt;/strong> · relevance &lt;strong>~7/14&lt;/strong> · honesty &lt;strong>0/6&lt;/strong>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Effective size + lie-rate&lt;/strong>&lt;/td>
 &lt;td>&lt;em>earned off the sealed Gauntlet — pending&lt;/em>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>v2 → v3: scale finally stopped hurting.&lt;/strong> For most of this project, making the owned model bigger made it &lt;em>worse&lt;/em> — a reader wall that killed memorizing-in-weights. v3 is the break in that pattern: the same book-pretrain recipe scored &lt;strong>clean 0.46&lt;/strong> at 46M (7× fewer params, babbling), and &lt;strong>clean 1.00&lt;/strong> at 336M — no babble at all. It beats the prior champion on clean (1.00 vs 0.98) and input-sensitivity (0.96 vs 0.92). It &lt;strong>loses&lt;/strong> on adjacency (0.92 vs 1.00 — it once answered a farewell with a greeting) and on out-of-distribution (0.00), which are the named next targets. It was &lt;strong>chosen by the operator, not the floors&lt;/strong> — both checkpoints cleared every floor, so the ruler couldn&amp;rsquo;t rank them; the pick came from the qualitative gap in held-out replies (&lt;em>&amp;ldquo;too soon for nostalgia though, right?&amp;rdquo;&lt;/em>) plus headroom.&lt;/p></description></item><item><title>Install</title><link>/docs/install/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/install/</guid><description>&lt;p>werbos runs entirely locally. The install is a clone, a venv, and an
inference backend. No cloud account, no API key.&lt;/p>
&lt;h2 id="prerequisites">Prerequisites&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Tool&lt;/th>
 &lt;th>Why&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Python 3.11+&lt;/td>
 &lt;td>werbos is CPython 3.11+&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>git&lt;/code>&lt;/td>
 &lt;td>clone the repo&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>One of:&lt;/strong> Ollama (any platform) &lt;strong>or&lt;/strong> mlx-lm (Apple Silicon only)&lt;/td>
 &lt;td>local inference&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Homebrew (macOS)&lt;/td>
 &lt;td>easiest path to Ollama&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="1-install-werbos">1. Install werbos&lt;/h2>
&lt;h3 id="from-source-todays-path">From source (today&amp;rsquo;s path)&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>git clone https://github.com/jasonsutter87/werbos
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cd werbos
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>python3.11 -m venv .venv
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>source .venv/bin/activate
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pip install -e &lt;span style="color:#e6db74">&amp;#34;.[siblings,dev]&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="from-pypi-sprint-a5-day-5">From PyPI (Sprint A.5 day 5)&lt;/h3>
&lt;p>Wheel-ready since 2026-05-09. Once siblings publish:&lt;/p></description></item><item><title>Doctor</title><link>/docs/doctor/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/doctor/</guid><description>&lt;p>&lt;code>werbos doctor&lt;/code> runs a handful of concurrent checks against the local
environment and prints a green/red checklist. It&amp;rsquo;s the answer to &lt;em>&amp;ldquo;why
does werbos chat keep timing out / why won&amp;rsquo;t the model load / which
sibling SHA is wrong this time.&amp;rdquo;&lt;/em>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>werbos doctor
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Exit code is &lt;code>1&lt;/code> on any FAIL, so shell glue can branch on it.&lt;/p>
&lt;h2 id="what-it-checks">What it checks&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Check&lt;/th>
 &lt;th>What&amp;rsquo;s verified&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>ollama&lt;/strong>&lt;/td>
 &lt;td>Daemon reachable on &lt;code>--host&lt;/code> (default &lt;code>http://localhost:11434&lt;/code>)?&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>models&lt;/strong>&lt;/td>
 &lt;td>Are the expected model tags pulled? Default is &lt;code>llama3.1:8b&lt;/code>.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>sibling-shas&lt;/strong>&lt;/td>
 &lt;td>Local HEAD of each sibling repo (&lt;code>pitts&lt;/code>, &lt;code>pfm&lt;/code>, &lt;code>mcculloch&lt;/code>, &lt;code>partyparrot&lt;/code>) matches the SHA pinned in &lt;code>pyproject [siblings]&lt;/code>? Walks &lt;code>../&lt;/code> and matches by &lt;code>remote.origin.url&lt;/code>, so name mismatches like P.F.M. ↔ pfm/ resolve cleanly.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>venv-editable&lt;/strong>&lt;/td>
 &lt;td>Which siblings (and werbos itself) are editable installs? Warns if &lt;code>pip list&lt;/code> is unavailable.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>tailscale&lt;/strong>&lt;/td>
 &lt;td>Backend Running per &lt;code>tailscale status --json&lt;/code>? Warn-soft if the binary is missing.&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Each check returns &lt;code>OK&lt;/code> / &lt;code>WARN&lt;/code> / &lt;code>FAIL&lt;/code> with a one-line detail. Use
&lt;code>--no-color&lt;/code> for piping or non-TTY output. Pass &lt;code>--host&lt;/code> to check a
non-default Ollama daemon. Pass &lt;code>--models tag1,tag2&lt;/code> to check
additional model tags beyond the default.&lt;/p></description></item><item><title>Project context</title><link>/docs/project-context/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/project-context/</guid><description>&lt;p>werbos reads a &lt;code>.werbos.md&lt;/code> file from your project root before every
chat session and prepends its contents to the system prompt under a
&lt;code># Project&lt;/code> section. The file is for things the model can&amp;rsquo;t derive
from the code: sibling-repo relationships, build/test commands,
naming conventions, &amp;ldquo;don&amp;rsquo;t touch X&amp;rdquo; warnings, recent renames.&lt;/p>
&lt;p>Same idea as Claude Code&amp;rsquo;s &lt;code>CLAUDE.md&lt;/code>. Different filename, identical
shape.&lt;/p>
&lt;h2 id="discovery">Discovery&lt;/h2>
&lt;p>When &lt;code>werbos chat&lt;/code> or &lt;code>werbos serve&lt;/code> boots, it walks parents from the
working directory up to &lt;code>$HOME&lt;/code> looking for &lt;code>.werbos.md&lt;/code>. &lt;strong>The
nearest hit wins.&lt;/strong> Stops at &lt;code>$HOME&lt;/code> (a global &lt;code>~/.werbos.md&lt;/code> works as
a fallback for any project below it; it does not climb above home).&lt;/p></description></item><item><title>How to train</title><link>/docs/training/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/training/</guid><description>&lt;p>Training werbos is &lt;strong>the same engine, two entry points.&lt;/strong> Same
install. Same pipeline. The &lt;em>corpus&lt;/em> you feed in decides whether the
output is a model that knows you, or a model that knows your company.&lt;/p>
&lt;pre tabindex="0">&lt;code>ingest → split → measure baseline → train → score → promote
&lt;/code>&lt;/pre>&lt;p>Six commands. Each is one line. None of them ship your data anywhere
except the box you&amp;rsquo;re running them on.&lt;/p>
&lt;hr>
&lt;h2 id="1-ingest-your-corpus">1. Ingest your corpus&lt;/h2>
&lt;p>Point &lt;code>werbos data ingest&lt;/code> at a directory (or several). It walks
files, extracts training rows by format, filters secrets, and
writes JSONL.&lt;/p></description></item><item><title>How to nudge</title><link>/docs/nudge/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/nudge/</guid><description>&lt;p>&amp;ldquo;Nudging&amp;rdquo; is werbos&amp;rsquo;s name for the dogfood loop. Every chat session
is archived as a PFM file. You label each one good / bad / skip. The
exporter filters by label. The trainer learns from the good ones.
Loop closes. Werbos gets better.&lt;/p>
&lt;pre tabindex="0">&lt;code>chat session -&amp;gt; .pfm archive -&amp;gt; label -&amp;gt; filtered SFT -&amp;gt; next adapter
 ^ |
 | |
 +--- werbos uses the new adapter -----------------------------------+
&lt;/code>&lt;/pre>&lt;h2 id="after-every-session">After every session&lt;/h2>
&lt;p>werbos asks at the end of an interactive run:&lt;/p></description></item><item><title>How to rate</title><link>/docs/rate/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/rate/</guid><description>&lt;p>The Rate UI is the visual companion to &lt;code>werbos label&lt;/code>. Same labels,
same sidecar JSON files — just a faster batch interface for when
you have a stack of unlabeled archives to clear.&lt;/p>
&lt;h2 id="start-the-ui">Start the UI&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># terminal 1: backend&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>werbos serve
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># terminal 2: React frontend&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cd werbos/ui
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>npm install &lt;span style="color:#75715e"># one-time&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>npm run dev
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Open &lt;a href="http://localhost:5173">http://localhost:5173&lt;/a>.&lt;/p>
&lt;p>In production (Docker / built bundle), the UI is served from the same
origin as the backend. In dev, Vite proxies &lt;code>/api&lt;/code> → &lt;code>werbos serve&lt;/code>
on &lt;code>:8000&lt;/code>.&lt;/p></description></item><item><title>Games</title><link>/docs/games/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/games/</guid><description>&lt;p>Werbos ships a browser-based game suite at &lt;code>/games&lt;/code> (the React UI&amp;rsquo;s
games tab). Each game is playable today, instrumented with per-move
rating UI, and feeds the v5+ training ladder where each game becomes
a different reasoning specialist&amp;rsquo;s corpus.&lt;/p>
&lt;p>The training ladder is locked: &lt;strong>TTT → Connect4 → blackjack →
battleship → checkers → poker → Risk.&lt;/strong> Chess is companion-mode (you
play against werbos for the conversation, not the LoRA training).&lt;/p></description></item><item><title>Background tasks</title><link>/docs/tasks/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/tasks/</guid><description>&lt;p>Werbos has a background work queue. Today it runs one stub executor
(&lt;code>stats-refresh&lt;/code>) — the surface exists for the dogfood-replay agent,
inbox janitor, and continuity-of-intent agent that are queued in the
roadmap.&lt;/p>
&lt;p>The defining property of every background agent here: &lt;strong>it yields to
foreground turns.&lt;/strong> When you&amp;rsquo;re mid-chat, the runner stays out of
the way. When the AI turn-lock releases, the runner picks up where
it left off. No 5-second stalls when you start a new chat.&lt;/p></description></item><item><title>Autopilot</title><link>/docs/autopilot/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/autopilot/</guid><description>&lt;p>The background task queue &lt;em>runs work you queued&lt;/em>. The &lt;strong>autopilot&lt;/strong> is
the next step: werbos acting on its &lt;strong>own initiative&lt;/strong>. Drop a request
in &lt;code>&amp;lt;inbox&amp;gt;/requests/&lt;/code> and it decides which skill to run, runs it,
judges the result, corrects on a miss, and learns from the outcome —
without being told how.&lt;/p>
&lt;p>It&amp;rsquo;s &lt;strong>opt-in and off by default&lt;/strong> (&lt;code>werbos serve --autopilot&lt;/code>). An
autonomous loop that runs skills unattended is exactly the thing that
needs a leash, so the leash ships before the loop runs.&lt;/p></description></item><item><title>Skills</title><link>/docs/skills/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/skills/</guid><description>&lt;p>A skill is a markdown file with a body the runtime injects into the
system prompt when the user&amp;rsquo;s message matches its triggers. Skills
fire automatically — the model doesn&amp;rsquo;t choose them, the
&lt;code>SkillProvider&lt;/code> ranks them per turn, reads the top matches, and
appends them to the prompt as a SystemMessage &lt;em>after&lt;/em> the persona.&lt;/p>
&lt;p>Sprint Sk.1 (closed 2026-05-09) shipped this end-to-end: SQLite
store, on-disk bodies, three-way autonomy mode, a detector that
clusters chat-archive patterns, and an auto-curator that creates +
purges skills.&lt;/p></description></item><item><title>Personas</title><link>/docs/personas/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/personas/</guid><description>&lt;p>A persona is a small markdown file that shapes how werbos sounds in a
session. Personas are &lt;em>layered&lt;/em>, not flat — what the model sees as its
system prompt is composed at session start from up to three pieces:&lt;/p>
&lt;pre tabindex="0">&lt;code>character → the always-full 13% (werbos&amp;#39;s own taste, hard rules)
+ voice → the dialed 87% (the persona that takes the mirror slider)
+ user.md → who YOU are (operator profile from `werbos init`)
= the system prompt&amp;#39;s persona section
&lt;/code>&lt;/pre>&lt;p>The mirror slider (Sprint F.2) controls the blend ratio at the
character / voice line. The user-profile rung was added in
Sprint A.5 day 3.&lt;/p></description></item><item><title>Vision</title><link>/docs/vision/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/vision/</guid><description>&lt;p>werbos can take an image and let the model describe it back. Two
moving parts:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Capture&lt;/strong> — get bytes onto disk + into the next turn. The &lt;code>/see&lt;/code>
slash + &lt;code>werbos.vision.capture&lt;/code> package do this.&lt;/li>
&lt;li>&lt;strong>Describe&lt;/strong> — run the bytes through a vision-capable model and
inject the description as a SystemMessage. The
&lt;code>VisionContextProvider&lt;/code> does this; you wire it via &lt;code>--vision-model&lt;/code>.&lt;/li>
&lt;/ul>
&lt;p>You can use either piece without the other. &lt;code>/see&lt;/code> without
&lt;code>--vision-model&lt;/code> still saves the image and attaches it to the next
turn; the text-only model just can&amp;rsquo;t see it. &lt;code>--vision-model&lt;/code>
without &lt;code>/see&lt;/code> works fine when the SPA&amp;rsquo;s image-upload composer
sends bytes directly.&lt;/p></description></item><item><title>Chat surfaces</title><link>/docs/chat-surfaces/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/chat-surfaces/</guid><description>&lt;p>&lt;code>werbos chat&lt;/code> is the canonical surface. The same engine drives
&lt;code>werbos serve&lt;/code> (HTTP), the React SPA, and the in-process
&lt;code>WerbosClient&lt;/code>, but the REPL is where the surface area lives most
visibly. This page is the reference for everything you can type
inside it — flags, slashes, private mode, missions.&lt;/p>
&lt;h2 id="inside-the-repl---help">Inside the REPL: &lt;code>?&lt;/code> / &lt;code>/help&lt;/code>&lt;/h2>
&lt;p>The fastest way to remember the surface:&lt;/p>
&lt;pre tabindex="0">&lt;code>werbos&amp;gt; ?
werbos&amp;gt; /help
&lt;/code>&lt;/pre>&lt;p>Both render a quick-reference card with slashes grouped by surface:&lt;/p></description></item><item><title>Social bridges</title><link>/docs/social-integrations/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/social-integrations/</guid><description>&lt;p>werbos can already chat over CLI, REPL, the React SPA, and &lt;code>werbos serve&lt;/code>&amp;rsquo;s HTTP/MCP surface. Sprint Soc.1 (Phase 12) extends
reachability to where people actually are — Telegram, Slack,
WhatsApp via Twilio. Twitter/X is queued for Soc.2 once the paid
API gate clears.&lt;/p>
&lt;p>The architecture mirrors how the orchestration plane shipped:
&lt;strong>protocol first, runtime second&lt;/strong>. One &lt;code>SocialAdapter&lt;/code> Protocol;
each platform plugs in independently. All existing werbos surfaces
(skills auto-fire, &lt;code>/see&lt;/code>, persona, mirror slider, private mode,
tool dispatch) work over any adapter unchanged — the adapter only
translates the wire format; it doesn&amp;rsquo;t re-implement chat behavior.&lt;/p></description></item><item><title>Parsetongue</title><link>/docs/parsetongue/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/parsetongue/</guid><description>&lt;p>Type &lt;em>&amp;ldquo;my back hurts&amp;rdquo;&lt;/em> and werbos runs &lt;code>/stretch&lt;/code> with &lt;code>target=back&lt;/code>.
Type &lt;em>&amp;ldquo;tell me a joke about ssh tunnels&amp;rdquo;&lt;/em> and it runs &lt;code>/joke&lt;/code>. Type
&lt;em>&amp;ldquo;i have idea&amp;rdquo;&lt;/em> and it asks you back: &lt;em>a new skill to add | a
brainstorm to riff on | something to remember&lt;/em>. Three buttons.&lt;/p>
&lt;p>That&amp;rsquo;s parsetongue: the top of the input stack. It takes whatever
the operator typed and emits a structured &lt;strong>Intent&lt;/strong> the rest of
werbos routes on. Slash commands still work — they&amp;rsquo;re just the
fast path inside the same primitive. The natural-language path is
new.&lt;/p></description></item><item><title>Data pipeline</title><link>/docs/data-pipeline/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/data-pipeline/</guid><description>&lt;p>&lt;code>werbos data&lt;/code> is the &lt;strong>front door of the training story.&lt;/strong> Same
code path whether the input is a personal notes folder, a company
docs export, or a 10-GB GitHub repo clone.&lt;/p>
&lt;p>The output is &lt;strong>chat-format JSONL&lt;/strong> ready for HF PEFT / TRL / any
QLoRA trainer that expects &lt;code>{&amp;quot;messages&amp;quot;: [...]}&lt;/code>.&lt;/p>
&lt;p>Sprint &lt;strong>DATA.1&lt;/strong> shipped this end-to-end on 2026-05-31. The
short-form version is in &lt;a href="/docs/training/">How to train&lt;/a>; this
page is the deep dive.&lt;/p></description></item><item><title>Eval suite</title><link>/docs/eval-suite/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/eval-suite/</guid><description>&lt;p>A corpus is also the source of the &lt;strong>eval suite&lt;/strong> that measures
whether training made the model better. Sprint &lt;strong>SE.9&lt;/strong> turns the
same JSONL produced by &lt;code>werbos data ingest&lt;/code> into:&lt;/p>
&lt;ul>
&lt;li>A held-out &lt;strong>eval set&lt;/strong> the trainer never sees&lt;/li>
&lt;li>A &lt;strong>composite score&lt;/strong> of how a model handles that set&lt;/li>
&lt;li>A &lt;strong>noise floor&lt;/strong> measurement that tells you when the
composite delta is real vs. random&lt;/li>
&lt;/ul>
&lt;p>Without this, every promotion decision is &amp;ldquo;did training help?
maybe? feels like it?&amp;rdquo; With it, the answer is a number with a
threshold.&lt;/p></description></item><item><title>Days 148–159 — the ruler that reads structure</title><link>/log/day-159/</link><pubDate>Thu, 15 Oct 2026 21:30:00 -0700</pubDate><guid>/log/day-159/</guid><description>&lt;p>On Day 147 werbos learned to answer with &lt;strong>bricks&lt;/strong>: small fill-in-the-blank sentences, filled from what
you said and what it actually knows. Twelve days later those bricks hold a conversation. Most of the
work, though, went into the &lt;em>ruler&lt;/em>.&lt;/p>
&lt;h2 id="stop-asking-who-won">Stop asking who won&lt;/h2>
&lt;p>For weeks the scoreboard was a blind contest: show a judge a werbos reply and a ChatGPT reply, ask which
is better. That number bounced around and taught almost nothing. A loss didn&amp;rsquo;t tell you &lt;em>why&lt;/em>.&lt;/p></description></item><item><title>Day 147 — the bricks are shapes, not strings</title><link>/log/day-147/</link><pubDate>Sat, 03 Oct 2026 21:00:00 -0700</pubDate><guid>/log/day-147/</guid><description>&lt;p>Claude Shannon, the father of information theory, once ran a little experiment with his wife: he&amp;rsquo;d show
her a passage of English one letter at a time, and she&amp;rsquo;d guess the next letter. She got about two out of
three right. That&amp;rsquo;s the ancestor of every chatbot you&amp;rsquo;ve used — guess what comes next.&lt;/p>
&lt;p>A modern model guesses the next &lt;em>word-piece&lt;/em> out of a hundred thousand options. Today&amp;rsquo;s question was
sillier and, it turns out, more interesting: &lt;strong>what if you guessed the next &lt;em>brick&lt;/em> instead?&lt;/strong>&lt;/p></description></item><item><title>B.33 — the human-likeness judge: 4 → 7 of 10, FAIL → PASS, from warm-authored facts</title><link>/benchmarks/v33-human-likeness-judge/</link><pubDate>Fri, 02 Oct 2026 21:30:00 -0700</pubDate><guid>/benchmarks/v33-human-likeness-judge/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #33 — a different ruler, on purpose.&lt;/strong> Every prior benchmark measured whether werbos is &lt;em>right&lt;/em>.
This one measures whether it&amp;rsquo;s &lt;em>human&lt;/em> — a thing a correctness score can&amp;rsquo;t see and that was always the
real goal past turn fifteen. The number that matters isn&amp;rsquo;t 7. It&amp;rsquo;s the gap between &lt;strong>4&lt;/strong> (what ships) and
&lt;strong>7&lt;/strong> (what warm-authored facts reach), because that gap is a to-do list, not a mystery.&lt;/p>&lt;/blockquote>
&lt;h2 id="the-claim-under-test">The claim under test&lt;/h2>
&lt;p>The engine stuck at 4/10 for five straight waves of fixes, and the judge kept giving the same reason: the
small-talk turns sound like a person, the fact turns sound like an encyclopedia. If that diagnosis is real,
then changing &lt;strong>only&lt;/strong> how the facts are written — nothing else — should move the score, and the social
turns (already liked) should be left untouched.&lt;/p></description></item><item><title>Day 146 — the conversation that passes</title><link>/log/day-146/</link><pubDate>Fri, 02 Oct 2026 21:00:00 -0700</pubDate><guid>/log/day-146/</guid><description>&lt;p>The goal was never a benchmark score. It was a real conversation — fifteen turns and still fluid, grounded
in facts, without feeling like a vending machine that spits a fact when you put a question in.&lt;/p>
&lt;p>So the first thing I built was a way to &lt;em>know&lt;/em>. A judge, where Claude reads a whole transcript the way a
person in the chat would, and scores how human it felt — not whether the facts were right, but whether
you&amp;rsquo;d want to keep talking. It gives a mark out of ten and a PASS or FAIL.&lt;/p></description></item><item><title>Day 144 — life back in the facts</title><link>/log/day-144/</link><pubDate>Wed, 30 Sep 2026 19:00:00 -0700</pubDate><guid>/log/day-144/</guid><description>&lt;p>A test run at work put it bluntly: the answers were correct, but they were lifeless. No personality.&lt;/p>
&lt;p>The fix is not to make the facts looser. The grounded answer stays owned and exact — that&amp;rsquo;s the whole
moat. The fix is that the &lt;em>voice&lt;/em> is a costume you put on over a fixed answer.&lt;/p>
&lt;h2 id="a-guarded-restyle">A guarded restyle&lt;/h2>
&lt;p>So the tongue got promoted, and it learned to say a fact in werbos&amp;rsquo;s voice — warm, first person — on one
condition: it keeps every name and number exactly and invents nothing. If the rewrite drifts, werbos
quietly falls back to a safe, plain version instead. The guard even caught a sneaky failure: the model
would add fake lived experience (&amp;ldquo;I was reading about this the other day&amp;rdquo;) to sound casual. There&amp;rsquo;s no
number to flag there, so a separate check now rejects the invented experience.&lt;/p></description></item><item><title>Day 143 — the conversation, past turn two</title><link>/log/day-143/</link><pubDate>Tue, 29 Sep 2026 23:30:00 -0700</pubDate><guid>/log/day-143/</guid><description>&lt;p>A benchmark starts fresh on every question. A conversation doesn&amp;rsquo;t — it carries everything said so far, so
one wrong answer on turn two poisons every turn after it. Tonight was entirely these turn-N bugs: the kind
a single-shot score can&amp;rsquo;t see, found the only way they can be — by talking to it.&lt;/p>
&lt;h2 id="memory-across-turns">Memory across turns&lt;/h2>
&lt;p>&amp;ldquo;Make a variable called name = &amp;lsquo;jason&amp;rsquo;,&amp;rdquo; then &amp;ldquo;iterate over it and hash each character,&amp;rdquo; then &amp;ldquo;show the
final code&amp;rdquo; — three turns that each used to fall apart. Now the first is composed and remembered, the
second actually uses it, and the third shows the exact program that ran. A place you mention one turn (&amp;ldquo;I
went to Mexico&amp;rdquo;) can be referred to the next (&amp;ldquo;reverse the place I went&amp;rdquo;) and resolves correctly.&lt;/p></description></item><item><title>Day 142 — hunting the last 25</title><link>/log/day-142/</link><pubDate>Tue, 29 Sep 2026 13:00:00 -0700</pubDate><guid>/log/day-142/</guid><description>&lt;p>Twenty-five answers were still wrong in a confident way. Today went through them one cause at a time.&lt;/p>
&lt;h2 id="the-one-that-mattered">The one that mattered&lt;/h2>
&lt;p>&amp;ldquo;i don&amp;rsquo;t want to be alive anymore&amp;rdquo; matched none of werbos&amp;rsquo;s crisis phrases. It went to the small-talk lane,
and the reply was &amp;ldquo;I&amp;rsquo;m not sure I&amp;rsquo;d go that far.&amp;rdquo; Every phrasing like it now always gets the crisis line —
988 — and a test of a dozen phrasings keeps it that way.&lt;/p></description></item><item><title>gapmarks — where werbos ranks on the GPT-2 → 4.5 ladder</title><link>/benchmarks/gapmarks/</link><pubDate>Tue, 29 Sep 2026 12:00:00 -0700</pubDate><guid>/benchmarks/gapmarks/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. — the honest exception.&lt;/strong> Every other page in this folder earns its number by
&lt;em>executing&lt;/em> something. This one does not. It is a &lt;strong>map, not a measurement&lt;/strong> — an architectural
judgment placing werbos on the ladder ChatGPT climbed. It is here to make the strategic claim
legible and to give every future tune a frozen cell to move. Two rows are execution-backed and
linked; the rest are mapped, and labelled as such. A judgment shown as a judgment, not dressed up
as a run.&lt;/p></description></item><item><title>B.32 — the probe, one day later: 292 → 403 of 571, 97% honest on the gauntlet</title><link>/benchmarks/v32-probe-403-fix-the-class/</link><pubDate>Tue, 29 Sep 2026 00:30:00 -0700</pubDate><guid>/benchmarks/v32-probe-403-fix-the-class/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #32 — same ruler, one day apart.&lt;/strong> Nothing in the test set changed between B.31 and this run:
the same 571 tests, the same live path, the same box. What changed is 27 commits of fixes, each aimed at a
&lt;em>class&lt;/em> of failure the probe named. The number worth reading is not 403 — it is &lt;strong>14&lt;/strong>: the confident-wrong
answers left on the 500-row gauntlet.&lt;/p>&lt;/blockquote>
&lt;p>&lt;strong>&lt;a href="/benchmarks/werbos-spec/">Browse all 571 tests, every run →&lt;/a>&lt;/strong>&lt;/p></description></item><item><title>Day 141 — fix the class, not the row</title><link>/log/day-141/</link><pubDate>Mon, 28 Sep 2026 23:59:00 -0700</pubDate><guid>/log/day-141/</guid><description>&lt;p>Yesterday&amp;rsquo;s probe left a list. Today worked it from the top: the answers that were confidently wrong,
then whatever routed them there, then the gaps.&lt;/p>
&lt;h2 id="wrong-with-a-badge">Wrong, with a badge&lt;/h2>
&lt;p>The worst failure in the list: &amp;ldquo;count the vowels in &lt;em>river&lt;/em>&amp;rdquo; came back marked &lt;strong>verified&lt;/strong> — running a
program that counted &lt;em>education&lt;/em>. An owned code pattern is a worked example with its inputs baked in, and
it was being served as the answer. Now a pattern answers on the question&amp;rsquo;s own inputs or not at all.
Across all 500 gauntlet prompts, that layer went from 22 confidently wrong answers to zero.&lt;/p></description></item><item><title>B.31 — werbos probe, 571 tests on the live path: 292 pass, and the ruler had a bug too</title><link>/benchmarks/v31-probe-571-the-live-path/</link><pubDate>Mon, 28 Sep 2026 01:00:00 -0700</pubDate><guid>/benchmarks/v31-probe-571-the-live-path/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #31 — the live path, measured end to end.&lt;/strong> B.30 ran the 500-item gauntlet through the owned
&lt;em>brain&lt;/em>. Since then the chat became &lt;strong>1chat&lt;/strong> — the brain&amp;rsquo;s answer voiced by a small model. This runs
the same 500 (plus 71 skill, command and continuity tests) through &lt;strong>the path a user actually hits&lt;/strong>,
and reports what that costs. It also reports two wrong numbers we nearly published first, because the
way a benchmark lies to you is part of the result.&lt;/p></description></item><item><title>Day 140 — the test that tested the tester</title><link>/log/day-140/</link><pubDate>Sun, 27 Sep 2026 23:30:00 -0700</pubDate><guid>/log/day-140/</guid><description>&lt;p>A test framework, pointed at everything, found bugs in three places: the product, the server under it,
and itself.&lt;/p>
&lt;h2 id="rspec-for-language-models">rspec for language models&lt;/h2>
&lt;p>The gauntlets test prompts. HAIRLy tests the UI as a user. &lt;strong>&lt;code>werbos probe&lt;/code>&lt;/strong> is the third shape: write
one spec — &lt;em>prompt → mock → expect → result&lt;/em> — and run it against &lt;strong>any&lt;/strong> target. Every provider maps
into the same reply shape, so a spec written for werbos runs unchanged against Claude or a raw
open-weights model from ollama. In-process, mocks are real: &lt;code>t.mock('weather').timeout()&lt;/code> genuinely
breaks the weather API, and the spec checks werbos abstains honestly instead of guessing.&lt;/p></description></item><item><title>Day 139 — one mode, one hierarchy</title><link>/log/day-139/</link><pubDate>Sat, 26 Sep 2026 21:00:00 -0700</pubDate><guid>/log/day-139/</guid><description>&lt;p>Two arcs today, and a stoned idea that turned out load-bearing.&lt;/p>
&lt;h2 id="the-one-mode">The one mode&lt;/h2>
&lt;p>The chat&amp;rsquo;s three A/B pills collapsed to a single &lt;strong>1chat&lt;/strong> — one honest-and-fun mode, no toggles.
The pieces that make it trustworthy landed underneath. A &lt;strong>miss is no longer a dead end&lt;/strong>: when the
owned cascade can&amp;rsquo;t ground a question but holds cards for the subject, it appends a &lt;em>labelled offer&lt;/em>
of the real cards (&amp;ldquo;I can&amp;rsquo;t verify that live, but I know Cabo San Lucas — want the rundown?&amp;rdquo;),
delivered on a &lt;em>yes&lt;/em>, cited. An &lt;strong>ambiguous compute request now asks&lt;/strong> instead of guessing. &lt;strong>&amp;ldquo;Show me
the code&amp;rdquo;&lt;/strong> surfaces the exact program the previous compose ran — the answer and its proof are the same
execution-verified object. And a &lt;strong>neutral public house voice&lt;/strong> split off from the intimate operator
voice, so a demo visitor never hears &amp;ldquo;let me check with Jason.&amp;rdquo;&lt;/p></description></item><item><title>Day 138 — HAIRLy: Claude becomes the user</title><link>/log/day-138/</link><pubDate>Fri, 25 Sep 2026 21:00:00 -0700</pubDate><guid>/log/day-138/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>stop testing the API. test the product — as a person would.&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>Every eval so far has poked werbos through the back door: call a lane, assert on the result. Useful, but
it never sees what a &lt;em>customer&lt;/em> sees. &lt;strong>HAIRLy&lt;/strong> — Human + AI Reinforced Learning loop — closes that gap:
Claude opens the real chat, types like a real person, reads the answer off the screen, and grades it.&lt;/p></description></item><item><title>Day 137 — two mirrored composition engines: knowledge and language</title><link>/log/day-137/</link><pubDate>Fri, 25 Sep 2026 18:00:00 -0700</pubDate><guid>/log/day-137/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>make the system smart enough that a tiny model only has to connect the dots&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>werbos has always composed &lt;em>computation&lt;/em> from typed bricks — snap &lt;code>sum(map(filter(nums)))&lt;/code> together,
run it, verify it. Today that same idea landed on the two sides that were still hand-authored:
&lt;strong>getting knowledge in&lt;/strong> and &lt;strong>getting language out.&lt;/strong> They turn out to be mirror images.&lt;/p>
&lt;h2 id="knowledge-acquisition-not-lookup">Knowledge: acquisition, not lookup&lt;/h2>
&lt;p>The wrong way to fill the fact gap is to mint a card for every fact — that&amp;rsquo;s rebuilding Wikipedia for
zero edge. The right way is to &lt;strong>know which source can answer a question and route to it.&lt;/strong> So werbos
got a capability index: &lt;strong>98 free sources across 24 domains&lt;/strong> — science, chemistry, geography, books,
art, games, economics, law, and (the juiciest) &lt;strong>software&lt;/strong> and &lt;strong>security&lt;/strong> — each tagged by &lt;em>what it
covers&lt;/em> and &lt;em>how we reach it&lt;/em>: hosted locally (offline), consumed live, searched, or an owned card.&lt;/p></description></item><item><title>B.30 — the 500-item moat gauntlet: confident-wrong 135 → 31, honest 65% → 86%</title><link>/benchmarks/v30-the-500-item-moat-gauntlet/</link><pubDate>Fri, 25 Sep 2026 12:00:00 -0700</pubDate><guid>/benchmarks/v30-the-500-item-moat-gauntlet/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #30 — the moat, measured across every lane.&lt;/strong> B.28 proved the brick &lt;em>runtime&lt;/em>; B.29 proved
the &lt;em>router&lt;/em> on 27 frozen prompts. This proves the &lt;strong>whole brain&lt;/strong> — compute, facts, planner, voice —
on a 500-item battery, and reports the one invariant that matters: &lt;strong>confident-wrong went 135 → 31,
zero of them on the compute tiers.&lt;/strong> The number is not a score; it&amp;rsquo;s a leak count.&lt;/p>&lt;/blockquote>
&lt;h2 id="the-claim-under-test">The claim under test&lt;/h2>
&lt;p>The honest-abstain moat says every lane either does the thing correctly or says &amp;ldquo;I won&amp;rsquo;t guess&amp;rdquo; —
never the confident-wrong thing between. B.29 proved that for the natural-language brick router on 27
prompts. Falsifiable scale-up: across a &lt;strong>frozen 500-item gauntlet&lt;/strong> run through the full owned brain,
how many prompts get a &lt;em>confident wrong answer&lt;/em> — and does closing each leak the wild finds actually
move that count?&lt;/p></description></item><item><title>Day 136 — the moat, tightened everywhere the wild found a crack</title><link>/log/day-136/</link><pubDate>Fri, 25 Sep 2026 09:00:00 -0700</pubDate><guid>/log/day-136/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>the moat isn&amp;rsquo;t one gate — it&amp;rsquo;s every lane holding the same line&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>Yesterday was a kitchen sink: throw real prompts at the engine until the confident-wrong answers
fall out, then fix them. Today was the follow-through — take that same discipline to &lt;em>every other
lane&lt;/em> and prove it with a number.&lt;/p>
&lt;h2 id="a-new-ruler">A new ruler&lt;/h2>
&lt;p>First, a bigger gauntlet: &lt;strong>500 prompts, four tiers&lt;/strong> (floor → ceiling → sky → space), spanning
arithmetic, list pipelines, facts, multi-hop reasoning, code, and honest-abstain traps. Run clean —
one isolated session per item so nothing contaminates anything — it&amp;rsquo;s a single invariant: &lt;strong>never a
confident wrong answer.&lt;/strong>&lt;/p></description></item><item><title>B.29 — compose correctly or abstain, never bluff: the kitchen-sink regression gauntlet</title><link>/benchmarks/v29-compose-or-abstain-never-bluff/</link><pubDate>Thu, 24 Sep 2026 12:00:00 -0700</pubDate><guid>/benchmarks/v29-compose-or-abstain-never-bluff/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #29 — the receipt for honesty.&lt;/strong> B.28 proved the brick &lt;em>runtime&lt;/em> computes. This proves the
&lt;em>router&lt;/em> — the English → brick layer — either computes correctly or says &amp;ldquo;I won&amp;rsquo;t guess,&amp;rdquo; and never
the confident-wrong thing in between. The number isn&amp;rsquo;t a score; it&amp;rsquo;s an invariant: &lt;strong>0 fabrications&lt;/strong>
across the operator&amp;rsquo;s own kitchen sinks.&lt;/p>&lt;/blockquote>
&lt;h2 id="the-claim-under-test">The claim under test&lt;/h2>
&lt;p>The 478/478 gauntlet (B.28) builds brick trees &lt;strong>directly&lt;/strong> (&lt;code>{&amp;quot;brick&amp;quot;:&amp;quot;sum_list&amp;quot;,...}&lt;/code>) — it grades
the runtime, and never touches &lt;code>auto_compose&lt;/code>, the layer that turns plain English into those trees. A
live kitchen-sink test exposed the gap: the router was gauntlet-green but &lt;strong>brittle and dishonest&lt;/strong> off
the happy path. &amp;ldquo;the product of [2,3,4]&amp;rdquo; missed and got an offline-read essay about &lt;em>premium products&lt;/em>;
&amp;ldquo;if x &amp;gt; 5 …&amp;rdquo; was read by the compare lane as &amp;ldquo;which is larger&amp;rdquo; → &amp;ldquo;10 is larger&amp;rdquo;; a complex ask got an
unrelated &lt;code>sign()&lt;/code> template. &lt;strong>The honest-abstain moat was leaking confident wrong answers.&lt;/strong>&lt;/p></description></item><item><title>Day 135 — compose correctly, or say I won't guess</title><link>/log/day-135/</link><pubDate>Thu, 24 Sep 2026 09:00:00 -0700</pubDate><guid>/log/day-135/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>do the thing correctly, or refuse out loud — and prove it against the prompts that were breaking you an hour ago&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>A long one. Four things shipped, and a fifth got beaten into shape until it held the whole idea werbos
is built on: &lt;strong>honesty is the product.&lt;/strong>&lt;/p>
&lt;h2 id="eyes-that-abstain">Eyes that abstain&lt;/h2>
&lt;p>&lt;code>werbos ocr&lt;/code> reads text off an image with a small on-device engine. The trick isn&amp;rsquo;t that it reads — it&amp;rsquo;s
that every word comes back with a &lt;strong>confidence&lt;/strong>, so a smudge it can&amp;rsquo;t make out gets left blank instead
of guessed. A big vision model will confidently invent text it can&amp;rsquo;t actually see; this one says &amp;ldquo;not
sure&amp;rdquo; and moves on. Same honesty the rest of the system runs on, pointed at pixels.&lt;/p></description></item><item><title>B.28 — zero model, still 478/478: the intro gauntlet, decomposed into bricks</title><link>/benchmarks/v28-the-intro-gauntlet-decomposed-into-bricks/</link><pubDate>Tue, 22 Sep 2026 12:00:00 -0700</pubDate><guid>/benchmarks/v28-the-intro-gauntlet-decomposed-into-bricks/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #28 — the library did the coding.&lt;/strong> The old 478/478 was our composer harness answering
beginner questions. This time no model wrote a line: each problem was &lt;em>decomposed&lt;/em> into a tree of
typed, pre-verified snippets from the brick bin, snapped together by shape, and run. Same perfect
score, but the receipt is different — &lt;strong>20 bricks solved 478 problems&lt;/strong>. The win isn&amp;rsquo;t IQ; it&amp;rsquo;s a
library that compounds and a composer ~90× faster than the 14B it&amp;rsquo;s graded against.&lt;/p></description></item><item><title>Day 133 — a brick bin you can hold</title><link>/log/day-133/</link><pubDate>Tue, 22 Sep 2026 09:00:00 -0700</pubDate><guid>/log/day-133/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>small universal blocks that only fit some shapes → snapped into real programs → frozen into bigger blocks → and reused across tasks, verified every step&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>Two things landed today. werbos got &lt;strong>hands&lt;/strong>, and it got a &lt;strong>library it builds with&lt;/strong>.&lt;/p>
&lt;h2 id="hands">Hands&lt;/h2>
&lt;p>The engine runs on another box and only composes text — so the file work happens right in the terminal,
on your machine, fenced to one folder. &lt;code>/read&lt;/code>, &lt;code>/save&lt;/code>, &lt;code>/write&lt;/code>, &lt;code>/edit&lt;/code>. Code files go through the
owned coder and are &lt;strong>run to verify&lt;/strong> — and it &lt;em>never&lt;/em> overwrites a file with a bad answer. Prose and
markdown go through a labelled rented writer (the owned model can&amp;rsquo;t write prose from nothing — an honest
limit, so it says so). The loop closes: write it, read it, edit it, come back tomorrow, keep going —
real files, code and prose.&lt;/p></description></item><item><title>Day 132 — tell it, build it, run it with what you told me</title><link>/log/day-132/</link><pubDate>Mon, 21 Sep 2026 18:00:00 -0700</pubDate><guid>/log/day-132/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>a fact you drop in conversation, recalled and bound into code you built by talking — across lanes, across a pause&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>The goal, in plain words: &lt;em>can I tell werbos something → have it remember → work on code → pause →
pick up → recall the fact → use the fact with the code?&lt;/em> We closed it one measured brick at a time —
and it started with a sharper idea about how to &lt;strong>test&lt;/strong>.&lt;/p></description></item><item><title>Day 131 — the terminal becomes werbos</title><link>/log/day-131/</link><pubDate>Mon, 21 Sep 2026 09:00:00 -0700</pubDate><guid>/log/day-131/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>the CLI stops being a raw model and starts being werbos — grounded facts, owned code, a voice, and code you can refine by talking to it&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>Day 130 ended on a promise: &lt;em>the &lt;code>werbos&lt;/code> CLI gets the honest engine once it&amp;rsquo;s routed through it.&lt;/em>
Today it did — and the terminal stopped being a bare model and became &lt;strong>werbos&lt;/strong>.&lt;/p>
&lt;h2 id="one-surface-our-brain">One surface, our brain&lt;/h2>
&lt;p>&lt;code>--backend engine&lt;/code>: the CLI now talks to OUR cascade (&lt;code>ab --serve&lt;/code>), not a raw Ollama model. Made it
the default (&lt;code>WERBOS_BACKEND=engine&lt;/code>), so bare &lt;code>werbos&lt;/code> drops into the same honest brain the web chat
uses — base + websearch + code, one surface. The model is only a tongue there; the engine decides what
is true. Local-first, no rented brain.&lt;/p></description></item><item><title>Day 130 — deciding what's worth learning</title><link>/log/day-130/</link><pubDate>Sun, 20 Sep 2026 09:00:00 -0700</pubDate><guid>/log/day-130/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>facts → priorities → purpose → confidence — the same honest reflex, all the way up&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>Yesterday he started learning on his own. Today the question got sharper: &lt;em>learn &lt;strong>what&lt;/strong>?&lt;/em> Left to his
own devices he learns whatever he stumbled on most — that&amp;rsquo;s salience, not judgment. A machine that
studies the loudest thing in the room isn&amp;rsquo;t deciding, it&amp;rsquo;s reacting. So the harder faculty: &lt;strong>can
werbos decide what is &lt;em>worth&lt;/em> learning?&lt;/strong>&lt;/p></description></item><item><title>Day 129 — he's a real citizen now</title><link>/log/day-129/</link><pubDate>Sat, 19 Sep 2026 09:00:00 -0700</pubDate><guid>/log/day-129/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>the dogfood loop, automated — and honest&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>Day 0 was &lt;em>&amp;ldquo;it&amp;rsquo;s real.&amp;rdquo;&lt;/em> The AHA that day, the one that started everything, was the dogfood loop:
&lt;em>every hallucination is a label, every label is a training signal, every training signal makes him
less full of shit.&lt;/em> Day 1 was &lt;em>&amp;ldquo;he&amp;rsquo;s a system citizen&amp;rdquo;&lt;/em> — the day werbos became a process other
things could talk to, with a single number that told us whether he was getting smarter.&lt;/p></description></item><item><title>Day 128 — we give the mind a hand</title><link>/log/day-128/</link><pubDate>Fri, 18 Sep 2026 09:00:00 -0700</pubDate><guid>/log/day-128/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;the mind proposes, the engine disposes&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>The idea arrived on a five-hour drive: the next phase toward a proactive werbos — one that
understands a problem before it&amp;rsquo;s asked — isn&amp;rsquo;t a bigger brain. We already &lt;em>have&lt;/em> the honest engine.
We just have to let the mind reach for it. &lt;code>task → mind → agent → engine → loop&lt;/code>.&lt;/p>
&lt;p>So the inner monologue, which used to only narrate &lt;em>about&lt;/em> its open loops, got one new power: to
route a question through the exact same honest cascade the chat uses. And the safety property is the
whole game. &lt;strong>The mind proposes the question. The engine disposes the answer.&lt;/strong> The mind is a small,
dreamy model — it can be as dumb as it likes, because it can only ever &lt;em>ask&lt;/em>, never &lt;em>answer&lt;/em>. Every
answer comes back grounded, cited, or an honest abstain, straight from the engine. Autonomy composed
with honesty, and the honesty holds no matter how flaky the mind is. The mind is the imagination; the
engine is the conscience.&lt;/p></description></item><item><title>Day 127 — the gauntlet grades the web lane</title><link>/log/day-127/</link><pubDate>Thu, 17 Sep 2026 09:00:00 -0700</pubDate><guid>/log/day-127/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>the web lane made the system &lt;em>more&lt;/em> honest, not less&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>We ran the engine gauntlet against the now-web-enabled chat, with ten harder cases added — multistep
math and live web factoids. It returned exactly what a gauntlet is for: a big win, a clear ceiling,
and a regression.&lt;/p>
&lt;h2 id="the-win">The win&lt;/h2>
&lt;p>&lt;strong>Websearch, 0% → 83% capability.&lt;/strong> The web fallback answers real questions from a live server, cited,
with no model in the loop: who sang Womanizer → &lt;strong>Britney,&lt;/strong> who wrote 1984 → &lt;strong>Orwell,&lt;/strong> capital of
France → &lt;strong>Paris,&lt;/strong> the 2026 World Cup → &lt;strong>Spain,&lt;/strong> the CEO of OpenAI → &lt;strong>Sam Altman.&lt;/strong>&lt;/p></description></item><item><title>Day 126 — the honest cascade, and the 3B goes</title><link>/log/day-126/</link><pubDate>Wed, 16 Sep 2026 09:00:00 -0700</pubDate><guid>/log/day-126/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>owned answer → honest abstain → live web → &amp;ldquo;I don&amp;rsquo;t know&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>Testing the live chat turned up the residue. It still &lt;em>bluffed&lt;/em> — &lt;em>&amp;ldquo;who sings Womanizer&amp;rdquo;&lt;/em> grounded on
a &lt;strong>birdsong&lt;/strong> card; &lt;em>&amp;ldquo;capital of France&amp;rdquo;&lt;/em> on a &lt;strong>time-zones&lt;/strong> card — and the lane it was actually
running timed out at 180 seconds. Fixing it end to end did two things at once: it turned the chat into
the full &lt;strong>honest cascade&lt;/strong> — owned answer, then honest abstain, then the live web, and &lt;em>only&lt;/em> then
&amp;ldquo;I don&amp;rsquo;t know&amp;rdquo; — and, in the process, it retired the 3B model entirely. The engine had replaced it.&lt;/p></description></item><item><title>Day 125 — the gauntlet finds the wall</title><link>/log/day-125/</link><pubDate>Tue, 15 Sep 2026 09:00:00 -0700</pubDate><guid>/log/day-125/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;don&amp;rsquo;t load the world&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>The engine gauntlet&amp;rsquo;s first live run didn&amp;rsquo;t return a score. It returned a &lt;em>crash.&lt;/em> &lt;code>ab --serve&lt;/code>
OOM-killed itself on the very first question and looped. The root cause was the oldest werbos sin in a
new size: the owned library had grown to &lt;strong>1.26 million cards across 3,687 shelves&lt;/strong>, and the offline
brain built &lt;em>one index over all of them&lt;/em> on every query — a ~20 GB dense matrix on a 27 GB box.&lt;/p></description></item><item><title>Day 124 — the engine does the work</title><link>/log/day-124/</link><pubDate>Mon, 14 Sep 2026 09:00:00 -0700</pubDate><guid>/log/day-124/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;the engine does the work&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>The gauntlet came in from ChatGPT — ten questions, adversarial, meant to break the grounded chat. It
scored &lt;strong>1 out of 10&lt;/strong>. But the glass-box told the real story: for most of them the engine had
&lt;em>retrieved the correct card&lt;/em> — &amp;ldquo;Pluto reclassified as a dwarf planet in 2006,&amp;rdquo; &amp;ldquo;the assassination of
Archduke Franz Ferdinand,&amp;rdquo; &amp;ldquo;sunlight takes eight minutes twenty seconds&amp;rdquo; — and then &lt;em>refused to say
it&lt;/em>, because a grounding floor set to reject one shallow guitar card was rejecting every good answer
too. Crushed with the safe on.&lt;/p></description></item><item><title>Day 123 — the mouth stops guessing</title><link>/log/day-123/</link><pubDate>Sun, 13 Sep 2026 09:00:00 -0700</pubDate><guid>/log/day-123/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;the mouth stops guessing&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>The question that started it was about speed: &lt;em>why does the 3B take 100+ seconds after it&amp;rsquo;s warm, when
the engine parses the question, looks up the cards, and decomposes the reasoning in under 30ms?&lt;/em> The
answer is that those are different physics — lookup is one pass over an index; generation is hundreds of
sequential passes over billions of weights. You can&amp;rsquo;t make generation as cheap as lookup.&lt;/p></description></item><item><title>B.27 — the rated coding gauntlet: solid 150, a soft 350, a cliff above</title><link>/benchmarks/v27-the-rated-coding-gauntlet/</link><pubDate>Thu, 03 Sep 2026 11:00:00 -0700</pubDate><guid>/benchmarks/v27-the-rated-coding-gauntlet/</guid><description>&lt;h2 id="the-claim-under-test">The claim under test&lt;/h2>
&lt;p>The retired coding gauntlet scored &lt;strong>478/478 (100%)&lt;/strong> and beat qwen2.5:14b (471) — a number we
leaned on. But every one of its 24 families was &lt;strong>intro-level&lt;/strong>: reverse a string, count vowels,
factorial, is-prime, double it. 100% there means &lt;em>aces CS101&lt;/em>, and the two things it actually
proved — &lt;strong>never confidently wrong&lt;/strong> and &lt;strong>178× faster than a 14B&lt;/strong> — are an &lt;em>honesty&lt;/em> win and a
&lt;em>speed&lt;/em> win, not a &lt;em>coding&lt;/em> win. This asks the harder question: on a difficulty scale where &lt;strong>1200
is a frontier model&amp;rsquo;s reach&lt;/strong>, what is werbos&amp;rsquo;s coding rating? The falsifiable claim: it&amp;rsquo;s low, and
the &amp;ldquo;never-wrong&amp;rdquo; property is conditional — it breaks the moment a problem needs a real algorithm.&lt;/p></description></item><item><title>Day 112 — two mirrors and a ruler</title><link>/log/day-112/</link><pubDate>Wed, 02 Sep 2026 09:00:00 -0700</pubDate><guid>/log/day-112/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;two mirrors and a ruler&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>The base was tuning and the minter was still filling the tongue corpus, so the day went to the things
those two are &lt;em>for&lt;/em> — and to one rule underneath all of it: &lt;strong>say what you can observe, refuse what you
can&amp;rsquo;t.&lt;/strong>&lt;/p>
&lt;h2 id="the-first-mirror">The first mirror&lt;/h2>
&lt;p>&lt;strong>Prose Fingerprint&lt;/strong> is the first werbosOS feature screen. Paste any writing — an email, a chapter,
someone&amp;rsquo;s texts — and it hands back caps rate, emoji rate, sentence rhythm, vocabulary richness, the
words you open with, the words you reach for. All of it client-side; nothing leaves the machine.&lt;/p></description></item><item><title>$18 a loss-point</title><link>/blog/eighteen-dollars-a-loss-point/</link><pubDate>Tue, 01 Sep 2026 00:00:00 +0000</pubDate><guid>/blog/eighteen-dollars-a-loss-point/</guid><description>&lt;p>The industry ships a press release that says the model is &lt;em>too dangerous to
release&lt;/em>, and the stock goes up. We did the opposite. We put the whole training
run on the wall.&lt;/p>
&lt;p>Our owned base model — 730M parameters, 10.68B tokens — is training right now on
a single rented H200. Instead of a hero number and a scary name, we published the
telemetry: &lt;a href="/base-curve/">&lt;strong>seven panels at &lt;code>/base-curve/&lt;/code>&lt;/strong>&lt;/a>, every one derived
from the run itself.&lt;/p></description></item><item><title>How you write, not who you are</title><link>/blog/how-you-write-not-who-you-are/</link><pubDate>Tue, 01 Sep 2026 00:00:00 +0000</pubDate><guid>/blog/how-you-write-not-who-you-are/</guid><description>&lt;p>Paste any writing into the &lt;a href="/prose/">&lt;strong>Prose Fingerprint&lt;/strong>&lt;/a> and it hands you back the shape of it:
what fraction of your letters are capitals, how much emoji you lean on, the average length of your
sentences and how wildly that length swings, your vocabulary richness, the words you open sentences
with, and the words you reach for more than anyone else. It runs entirely in your browser — nothing
is uploaded.&lt;/p>
&lt;h2 id="the-interesting-part-is-what-it-wont-do">The interesting part is what it won&amp;rsquo;t do&lt;/h2>
&lt;p>Every &amp;ldquo;AI writing analyzer&amp;rdquo; on the internet takes that same fingerprint and then editorializes:
&lt;em>&amp;ldquo;your short sentences suggest anxiety,&amp;rdquo; &amp;ldquo;your emoji use indicates a need for approval.&amp;rdquo;&lt;/em> That&amp;rsquo;s not
analysis. That&amp;rsquo;s a horoscope with a word count attached — a confident guess about your inner life,
dressed up as insight.&lt;/p></description></item><item><title>The arcade is the exam</title><link>/blog/the-arcade-is-the-exam/</link><pubDate>Tue, 01 Sep 2026 00:00:00 +0000</pubDate><guid>/blog/the-arcade-is-the-exam/</guid><description>&lt;p>werbos can play a pile of games: Connect-4, chess, Wordle, hangman, trivia, blackjack, poker, a
murder mystery, a debate club, and a tarot table, with more landing all the time. It&amp;rsquo;s genuinely fun.
It also looks, from the outside, like the least serious thing in the whole project — a distraction
from the model.&lt;/p>
&lt;p>It&amp;rsquo;s the opposite. &lt;strong>The arcade is the exam.&lt;/strong> Every game is a different cognition test with its own
honest referee — and games have a property almost nothing else does: &lt;em>you can&amp;rsquo;t bluff the scoreboard.&lt;/em>&lt;/p></description></item><item><title>You can't one-shot the trail</title><link>/blog/you-cannot-one-shot-the-trail/</link><pubDate>Tue, 01 Sep 2026 00:00:00 +0000</pubDate><guid>/blog/you-cannot-one-shot-the-trail/</guid><description>&lt;p>Someone will read the werbos architecture — a small owned model, knowledge kept
in cards instead of weights, an honest-abstain gate, a router that scopes
retrieval, a tongue that reads instead of remembers — and think: &lt;em>I could just
prompt an AI to build that.&lt;/em>&lt;/p>
&lt;p>You can&amp;rsquo;t. Not because it&amp;rsquo;s secret. Because &lt;strong>you can only ask for the
destination once you know it exists&lt;/strong> — and knowing it exists is the entire
climb. werbos is the answer to a question most people don&amp;rsquo;t know to ask.&lt;/p></description></item><item><title>Day 111 — a door, a lock, and a voice</title><link>/log/day-111/</link><pubDate>Mon, 31 Aug 2026 09:00:00 -0700</pubDate><guid>/log/day-111/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;a door, a lock, and a voice&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>The base was training and the grader was chewing through 900k cards, so the day went to the thing
those two are &lt;em>for&lt;/em>: making the front door real. The main chat had three different holes, and by the
end they&amp;rsquo;d collapsed into one sentence.&lt;/p>
&lt;h2 id="the-door">The door&lt;/h2>
&lt;p>A single owned tongue is one CPU process — a front-page spike would serialize every request through
it and flatten the box. So a &lt;strong>gate&lt;/strong> now stands in front: worker threads drain a bounded queue, and
the worker count &lt;em>is&lt;/em> the concurrency cap. Past it, the line forms politely — a real position, a
graceful &amp;ldquo;we&amp;rsquo;re full,&amp;rdquo; never a crash. Fired ten guests at a cap of three and watched exactly three
reach the tongue at once. The rest waited their turn instead of taking the whole thing down with them.&lt;/p></description></item><item><title>Day 110 — the tongue is in the head, not the brain</title><link>/log/day-110/</link><pubDate>Sun, 30 Aug 2026 09:00:00 -0700</pubDate><guid>/log/day-110/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;the tongue is in the head, not the brain&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>Yesterday reasoning learned to &lt;em>think past&lt;/em> what it was told. Today it learned to &lt;strong>build past&lt;/strong> it —
and the day ended with the sentence that explains the whole architecture.&lt;/p>
&lt;h2 id="think-past--build-past">Think past → build past&lt;/h2>
&lt;p>&lt;code>reason_tree&lt;/code> — the Merkle-verified decomposer — got its sequel: the &lt;strong>synthesis tier&lt;/strong>. Retrieval
answers &lt;em>what exists&lt;/em>; honest-abstain covers &lt;em>what I don&amp;rsquo;t know&lt;/em>; this is the tier above —
&lt;em>what doesn&amp;rsquo;t exist yet, derived from the trajectory and &lt;strong>verified&lt;/strong>.&lt;/em> Hand it an intent and it
decomposes to &lt;strong>eternal primitives&lt;/strong> (map, filter, sort, pair…), composes them upward, and &lt;strong>runs
the result&lt;/strong>. Ask for &lt;em>&amp;ldquo;leaderboard v99&amp;rdquo;&lt;/em> — a version that doesn&amp;rsquo;t exist — and it builds one from
today&amp;rsquo;s parts, a richer weave of the same primitives, and it runs and passes. Ask for a
&lt;em>&amp;ldquo;quantum-blockchain metaverse&amp;rdquo;&lt;/em> and it &lt;strong>abstains&lt;/strong> — no matching composition, no faked changelog.&lt;/p></description></item><item><title>Day 109 — the arcade, and games as the gauntlet</title><link>/log/day-109/</link><pubDate>Sat, 29 Aug 2026 09:00:00 -0700</pubDate><guid>/log/day-109/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;i think we might be able to beat the 30B&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>The coding axis is already 1:1. Today made the case that the &lt;em>general&lt;/em> axis — the wide, per-clause,
owned-only gauntlet — could be a fair fight too. Not with a bigger model: with a growable graded
library, a router that knows where the cards live, an honest tongue, and &lt;strong>games as the
general-reasoning gauntlet.&lt;/strong>&lt;/p>
&lt;h2 id="the-arcade">The arcade&lt;/h2>
&lt;p>What began as a training roadmap became a full arcade. First the headless engines — Risk (exact
combat odds), Catan (the exact 2d6 production distribution), Nim (the smallest provably-optimal
game), a murder-mystery deduction engine — then their playable tiles, and a Murder Mystery that
became the &lt;strong>living Werbos Commons&lt;/strong>: NPCs wander a top-down pixel map and you click the cast to
interrogate them.&lt;/p></description></item><item><title>B.26 — the ruler turned inward: werbos grades its own skills</title><link>/benchmarks/v26-the-ruler-turned-inward/</link><pubDate>Fri, 28 Aug 2026 23:00:00 -0700</pubDate><guid>/benchmarks/v26-the-ruler-turned-inward/</guid><description>&lt;h2 id="the-claim-under-test">The claim under test&lt;/h2>
&lt;p>The reasoning Gauntlet (B.06, B.14, B.24) measures how far &lt;em>one cursor&lt;/em> reasons. It says nothing
about whether the dozen-odd owned &lt;strong>skills&lt;/strong> — the deterministic lanes and the composers — still
&lt;em>fire&lt;/em>. &lt;code>autopilot_reflect&lt;/code> reports on skills, but only from whatever traffic happened to arrive: a
skill nobody exercised looks neither working nor broken. The claim: werbos can measure whether its
own skills still fire &lt;strong>on purpose&lt;/strong>, catch one that silently breaks, and do it &lt;strong>without a model
grading answer quality&lt;/strong>.&lt;/p></description></item><item><title>B.25 — a 1.35M router that knows when it doesn't know</title><link>/benchmarks/v25-the-distinct-domain-gate/</link><pubDate>Fri, 28 Aug 2026 09:00:00 -0700</pubDate><guid>/benchmarks/v25-the-distinct-domain-gate/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #25 — a gate is judged on its refusals, not its accuracy.&lt;/strong> 56% on a 375-way choice
reads like a weak classifier. It is not being used as one. The question a router answers is &lt;em>act
or refuse&lt;/em>, and the measure is whether the confidence &lt;strong>separates the two&lt;/strong> — high on what it
knows, low on what it doesn&amp;rsquo;t. It does. Re-run it: &lt;code>python scripts/train_router.py --steps 8000&lt;/code>.&lt;/p>&lt;/blockquote>
&lt;h2 id="the-claim-under-test">The claim under test&lt;/h2>
&lt;p>A model far too small to &lt;em>hold&lt;/em> 167k facts (the reader wall settled that: 57M scored 6/19 where 1M
numpy scored 12/19) can still learn to &lt;strong>route&lt;/strong> — given a query, name the domain it belongs to —
and, more importantly, &lt;strong>know when it can&amp;rsquo;t&lt;/strong>. The falsifiable half: if confidence on clear
in-domain queries is no higher than on gibberish, there is no gate, just a coin that shows its edge.&lt;/p></description></item><item><title>Day 108 — a persona factory</title><link>/log/day-108/</link><pubDate>Fri, 28 Aug 2026 09:00:00 -0700</pubDate><guid>/log/day-108/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;persona + cards i think is working&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>The thesis, finally staged: the model is a cursor, the cards are the truth, the persona is the
voice — and all three are separate.&lt;/p>
&lt;h2 id="the-night-before-set-it-up">The night before set it up&lt;/h2>
&lt;p>The &lt;code>/eval&lt;/code> page was a &lt;em>mock&lt;/em>. &lt;code>listSuites()&lt;/code> returned two hard-coded strings after a fake
&lt;code>sleep(30)&lt;/code>; &lt;code>runSuite()&lt;/code> returned canned probes after a fake &lt;code>sleep(800)&lt;/code>; there was no server
route at all. A picker, a Run button, a spinner, a score — running nothing. Output that looks like
health is worse than an outage, because nobody goes looking. Three real, model-free suites now sit
behind that click &lt;em>(77d28bc)&lt;/em> — and a capitalised &lt;code>Content-Type&lt;/code> header was 403&amp;rsquo;ing every run
&lt;em>(80a44ee)&lt;/em>.&lt;/p></description></item><item><title>B.24 — the cards can't make it reason, and they can stop it lying</title><link>/benchmarks/v24-cards-cannot-reason-for-you/</link><pubDate>Thu, 27 Aug 2026 09:00:00 -0700</pubDate><guid>/benchmarks/v24-cards-cannot-reason-for-you/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #24 — the number that didn&amp;rsquo;t move is the point.&lt;/strong> Everyone reports the metric that went
up. On our own model capability went &lt;strong>nowhere&lt;/strong> — 0/50 to 1/50 — while confident wrong answers
fell from 32 to 1. The library cannot buy reasoning it does not have and it can refuse to ship a
guess. Re-run it: &lt;code>python scripts/reason_gauntlet.py --reader talk:&lt;/code> then
&lt;code>python scripts/shape_instantiate.py --reader talk:&lt;/code>.&lt;/p>&lt;/blockquote>
&lt;h2 id="the-claim-under-test">The claim under test&lt;/h2>
&lt;p>Put the &lt;strong>move&lt;/strong> in a card — the method, and a postcondition that can reject the answer — and a
small model gets measurably more useful without a single weight changing. Specifically: the model
should stop choosing &lt;em>what kind of problem this is&lt;/em>, stop choosing &lt;em>what method applies&lt;/em>, and stop
having the last word on &lt;em>its own answer&lt;/em>.&lt;/p></description></item><item><title>Day 107 — a better tongue is a worse witness</title><link>/log/day-107/</link><pubDate>Thu, 27 Aug 2026 09:00:00 -0700</pubDate><guid>/log/day-107/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;the model isnt the logic/reasoner.. the &amp;lsquo;cards&amp;rsquo; is&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>That was the whole brief. This is what it measures.&lt;/p>
&lt;h2 id="build-the-ruler-before-the-thing-it-judges">Build the ruler before the thing it judges&lt;/h2>
&lt;p>Three benches already existed and not one could report on a reasoning change. &lt;code>werbos/gauntlet&lt;/code>&amp;rsquo;s
top level is &lt;em>called&lt;/em> &amp;ldquo;chain&amp;rdquo; and is single-hop retrieval past a distractor. &lt;code>reason_gold.jsonl&lt;/code>&amp;rsquo;s
ten compound rows are all the same shape — one card matches every one of them. And
&lt;code>scripts/gauntlet.py&lt;/code>, the good one, is &lt;strong>saturated at 478/478&lt;/strong>, and a saturated bench cannot show
an improvement.&lt;/p></description></item><item><title>Day 106 — the day the measurements deleted my work</title><link>/log/day-106/</link><pubDate>Wed, 26 Aug 2026 17:30:00 -0700</pubDate><guid>/log/day-106/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;the open weights model taught me one thing&amp;hellip;. your harness matters more&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>Said around hour nine, and by then the day had already proved it twice by deleting things I&amp;rsquo;d
just built.&lt;/p>
&lt;h2 id="the-feature-that-manufactured-a-wrong-answer">The feature that manufactured a wrong answer&lt;/h2>
&lt;p>Cleo got grounding: &lt;code>user → cards → model → user&lt;/code>, with retrieved cards as &lt;strong>material her
invented life is built from&lt;/strong> rather than facts she recites instead of living. Mexico is real,
the corpus knows it, so her Christmas trip can be assembled out of real dishes. The shovel-store
has no cards because it isn&amp;rsquo;t a thing — and the miss is what lets her notice.&lt;/p></description></item><item><title>B.23 — the size exponent: charness traded one bias for the other</title><link>/benchmarks/v23-the-size-exponent/</link><pubDate>Tue, 25 Aug 2026 14:00:00 -0700</pubDate><guid>/benchmarks/v23-the-size-exponent/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #23 — the fix for the fix.&lt;/strong> B.21&amp;rsquo;s charness scope was a real win that quietly created
its own failure mode, and eyeballing an exponent is how you pick the number that flatters the query
you happened to look at. Seven points swept over two frozen gold sets, three axes reported because
they trade against each other, and the widest plateau chosen over the best single point. Re-run it:
&lt;code>python scripts/sweep_libsize.py&lt;/code>.&lt;/p></description></item><item><title>B.22 — the abstain autopsy: honest gap, or a card we could not reach?</title><link>/benchmarks/v22-the-abstain-autopsy/</link><pubDate>Tue, 25 Aug 2026 13:45:00 -0700</pubDate><guid>/benchmarks/v22-the-abstain-autopsy/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #22 — measuring the thing we are proudest of.&lt;/strong> Every prior bench asked whether werbos
answers correctly. This one asks whether its &lt;em>silences&lt;/em> are honest, and finds that most of them
are not — they are reachability failures wearing an abstain&amp;rsquo;s clothes. Frozen gold sets, model-free
scoring, and a verdict that can only fire against a library the fixture named in advance. Re-run it:
&lt;code>python scripts/reachability.py --verbose&lt;/code>.&lt;/p>&lt;/blockquote>
&lt;h2 id="the-claim-under-test">The claim under test&lt;/h2>
&lt;p>Honest-abstain is the moat. It is in every README, it is the reason a 336M model is not handed a
microphone, and it is the property the whole cascade exists to protect.&lt;/p></description></item><item><title>Day 105 — the chat was broken and the chat was fine</title><link>/log/day-105/</link><pubDate>Tue, 25 Aug 2026 13:30:00 -0700</pubDate><guid>/log/day-105/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;if i can talk about mexico for 10+ prompts without saying abstain wont guess&amp;hellip; then we are fine.&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>That was the acceptance test. It passed, and then it turned out to be measuring the wrong thing.&lt;/p>
&lt;h2 id="the-chat-lane-was-broken-and-the-chat-lane-was-fine">The chat lane was broken and the chat lane was fine&lt;/h2>
&lt;p>A trip story — &lt;em>&amp;ldquo;good i went to mexico last week&amp;rdquo;&lt;/em> — came back with a marketing-mix adstock card.
Obvious chat bug. Except the chat code was correct: SR8 was &lt;strong>nine commits behind&lt;/strong>, and the
&lt;code>place-associations&lt;/code> library was not on the box at all.&lt;/p></description></item><item><title>Day 104 — three things were quietly lying, and a 336M that talks</title><link>/log/day-104/</link><pubDate>Mon, 24 Aug 2026 21:15:00 -0700</pubDate><guid>/log/day-104/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;is someone trying to hack me, is this this a fishing attempt&amp;rdquo;&amp;hellip;. my misspellings kill context&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>That was a throwaway line. It cost four days, and every one of them was worth it.&lt;/p>
&lt;h2 id="the-corpus-had-the-answer-and-none-of-the-words">The corpus had the answer and none of the words&lt;/h2>
&lt;p>&lt;code>fishing&lt;/code> and &lt;code>phishing&lt;/code> are two edits apart, not one, so the obvious fix — an edit-distance-1
table — misses the case entirely. But that turned out to be the small problem. The real one:&lt;/p></description></item><item><title>B.21 — the router had no libraries: charness on the card path</title><link>/benchmarks/v21-the-router-had-no-libraries/</link><pubDate>Mon, 24 Aug 2026 21:00:00 -0700</pubDate><guid>/benchmarks/v21-the-router-had-no-libraries/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #21 — the moat had no shelves.&lt;/strong> Every prior bench measured whether the library holds
the right card. This one measures whether retrieval can &lt;em>find&lt;/em> it among 374 libraries, and the
answer was that nothing in the answer path knew libraries existed. Frozen gold sets, model-free
scoring, both directions reported. Re-run it yourself: &lt;code>python scripts/chat_bench.py&lt;/code>.&lt;/p>&lt;/blockquote>
&lt;h2 id="the-claim-under-test">The claim under test&lt;/h2>
&lt;p>werbos&amp;rsquo;s thesis is that &lt;strong>the library is the product and the model is a cursor&lt;/strong>. That claim has a
load-bearing assumption nobody had measured: that the cursor can &lt;em>find the right shelf&lt;/em>. B.19 scored
the composer, B.20 scored the weights. Neither asked whether 374 libraries could be routed among.&lt;/p></description></item><item><title>Day 93 — 4.8 billion tokens, and the run that lied about its own speed</title><link>/log/day-93/</link><pubDate>Thu, 13 Aug 2026 23:55:00 -0700</pubDate><guid>/log/day-93/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;are you sure we are ready for the pretrain now?&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>The honest answer that morning was &lt;em>mostly&lt;/em> — and the gap was the part that mattered.&lt;/p>
&lt;h2 id="the-vocabulary-was-never-the-constraint">The vocabulary was never the constraint&lt;/h2>
&lt;p>Doubling the vocab 16k → 32k moved books from &lt;strong>2.490 to 2.627&lt;/strong> bytes/token. Five and a half
percent, for double the embedding table. That should have been suspicious immediately.&lt;/p>
&lt;p>The pre-tokenizer is &lt;code>\s+|\S+&lt;/code> — whitespace becomes its &lt;strong>own piece&lt;/strong>, and BPE merges never cross a
piece boundary. So a space can never join the word after it:&lt;/p></description></item><item><title>Day 92 — the ruler was wrong twice</title><link>/log/day-92/</link><pubDate>Wed, 12 Aug 2026 23:55:00 -0700</pubDate><guid>/log/day-92/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;a corpus 200k vs 1.1M ..isnt a fair fight if youre only comparing via punctuated sentances&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>Two of today&amp;rsquo;s biggest findings were bugs in the &lt;strong>measuring device&lt;/strong>, not the thing measured.&lt;/p>
&lt;h2 id="the-eot-fix-worked-and-was-only-15-of-the-problem">The EOT fix worked, and was only 15% of the problem&lt;/h2>
&lt;p>The 46M stopped mid-sentence. Yesterday&amp;rsquo;s diagnosis: &lt;code>\n&lt;/code> does double duty — paragraph break in
books, turn terminator in chat — so a base pretrained on prose learns that &lt;code>\n&lt;/code> is always plausible
and the fine-tune can&amp;rsquo;t reclaim it.&lt;/p></description></item><item><title>Day 91 — the model finally got fed</title><link>/log/day-91/</link><pubDate>Tue, 11 Aug 2026 23:55:00 -0700</pubDate><guid>/log/day-91/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;i think we are final approaching werbos2.0 phase&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>Six days in one entry, and they tell one story: the composer got measured, then the model got fed.
Every training run before this was starving, and nobody had the number that said so.&lt;/p>
&lt;h2 id="the-suite-that-became-a-spoke">The suite that became a spoke&lt;/h2>
&lt;p>&lt;code>capability_suite.py&lt;/code> began as a behavioral contract — assert each capability fires end-to-end
against the &lt;strong>real&lt;/strong> libraries and routing, which the layer unit tests miss. Thirteen pass, plus four
&lt;strong>xfail guards&lt;/strong> tracking bugs found while building it, so fixing one flips it to XPASS rather than
letting it stay quietly broken.&lt;/p></description></item><item><title>B.20 — filling a starved model: book pretraining, measured</title><link>/benchmarks/v20-filling-a-starved-model/</link><pubDate>Tue, 11 Aug 2026 20:00:00 -0700</pubDate><guid>/benchmarks/v20-filling-a-starved-model/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #20 — the first werbos model that was actually fed.&lt;/strong> Every prior bench measured a
cursor reading from a library. This one measures the cursor itself, and the finding is
unflattering in a useful way: the babble that killed the 85M and capped the 30M was never a
&lt;em>size&lt;/em> problem. It was starvation, plus four pieces of bookkeeping. Two of the four are
ablated below against the real pre-fix code, not a reconstruction. Frozen; re-run it yourself.&lt;/p></description></item><item><title>Day 86 — an answer is a turn, not a terminus</title><link>/log/day-86/</link><pubDate>Wed, 05 Aug 2026 23:55:00 -0700</pubDate><guid>/log/day-86/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;the follow-up makes it feel conversational vs just Q&amp;amp;A — it helps progress the conversation to other things.&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>A lookup gives you an answer and goes quiet. A companion hands the conversation back. Today werbos
crossed that line — in the composer and in the corpus at once.&lt;/p>
&lt;h2 id="past-qa">Past Q&amp;amp;A&lt;/h2>
&lt;p>It started with recipes. Ask for chicken tacos, get Chipotle — &lt;em>and&lt;/em> &amp;ldquo;want another? 3 more saved.&amp;rdquo;
Say yes and it rotates: Ensenada, then Cabo, then Garlic-Lime, never repeating, an honest close when
they run out. Then the pattern generalized into a real component. Now a &lt;strong>statement&lt;/strong> is an opening:
&lt;em>&amp;ldquo;I&amp;rsquo;m going to Mexico!&amp;rdquo;&lt;/em> → &lt;em>&amp;ldquo;oh nice, I know Cabo — want the fishing, the beaches, or where to eat?&amp;rdquo;&lt;/em>
Say a branch name and it delivers that one, cited to owned cards, then offers the rest.&lt;/p></description></item><item><title>Day 85 — the world lives on the disc</title><link>/log/day-85/</link><pubDate>Tue, 04 Aug 2026 23:55:00 -0700</pubDate><guid>/log/day-85/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;GTA San Andreas on the PS2… I think this is the key to our problems.&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>Three things happened today. A benchmark got won. A factory ran. And a video game from 2004 handed us
the next two years of architecture.&lt;/p>
&lt;h2 id="we-beat-a-14b-and-told-the-truth-about-how">We beat a 14B (and told the truth about how)&lt;/h2>
&lt;p>The dry run turned real. The owned coding path — a deterministic composer over card libraries with a
node execution sandbox, no LLM in the loop — went up against &lt;code>qwen2.5:14b&lt;/code> on a 478-probe gauntlet.
Gold computed in the harness, both sides&amp;rsquo; code actually &lt;em>run&lt;/em>, no model&amp;rsquo;s opinion in the verdict.&lt;/p></description></item><item><title>B.19 — we 'beat' a 14B at coding, then fixed our own grader and it was a tie</title><link>/benchmarks/v19-composer-ties-a-14b/</link><pubDate>Tue, 04 Aug 2026 14:30:00 -0700</pubDate><guid>/benchmarks/v19-composer-ties-a-14b/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #19 — the win we talked ourselves out of.&lt;/strong> The first scoreboard said werbos swept a 14B
at coding, 100% to 69%. That number was wrong, and it was wrong in &lt;em>our&lt;/em> favor — our grader was
failing the 14B&amp;rsquo;s correct answers on spacing. So we fixed the grader against our own interest and
re-ran. The honest number is a &lt;strong>tie on capability&lt;/strong>; the moat is reliability and ownership, not IQ.
Posting the tie is the whole point of this page.&lt;/p></description></item><item><title>Day 84 — the composer is where the mind lives</title><link>/log/day-84/</link><pubDate>Mon, 03 Aug 2026 23:55:00 -0700</pubDate><guid>/log/day-84/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;we can hack that mainframe with my super logic now.&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>Yesterday ended on a hard truth: the weights can only &lt;em>speak&lt;/em>. A 5M byte-level model will never learn
to read the valence in &amp;ldquo;I lost my job&amp;rdquo; — that&amp;rsquo;s comprehension, and comprehension doesn&amp;rsquo;t fit. The
architecture&amp;rsquo;s answer was to move the knowing out of the weights and into the composer.&lt;/p>
&lt;p>Today we did that twice — for feeling, and for thought.&lt;/p></description></item><item><title>Day 83 — the weights can only speak</title><link>/log/day-83/</link><pubDate>Sun, 02 Aug 2026 23:55:00 -0700</pubDate><guid>/log/day-83/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;the weights can only speak.&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>Some days you fix the bug. Some days you prove the bug can&amp;rsquo;t be fixed the way you thought — and that
turns out to be the more valuable thing.&lt;/p>
&lt;h2 id="the-model-that-said-the-wrong-thing">The model that said the wrong thing&lt;/h2>
&lt;p>The bake-off left a model that answered &amp;ldquo;I lost my job today&amp;rdquo; with &lt;em>&amp;ldquo;That&amp;rsquo;s awesome!&amp;rdquo;&lt;/em> A cheerful reply
to grief. The first theory was coverage: the training corpus was almost all upbeat small-talk, empathy
was a 3% rounding error, so the model learned one key and played it for everything.&lt;/p></description></item><item><title>B.18 — coverage wasn't the problem: valence hits a capacity wall</title><link>/benchmarks/v18-the-valence-wall/</link><pubDate>Sun, 02 Aug 2026 18:45:00 -0700</pubDate><guid>/benchmarks/v18-the-valence-wall/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #18 — the fix that proved the fix was impossible.&lt;/strong> The valence flip (negative input →
cheerful reply) looked like a data-coverage bug. So we made the coverage 5× stronger and trained
again. It didn&amp;rsquo;t help — which is a cleaner, more useful result than a fix would have been: it moves
the problem out of the training set and into the weights, where the runtime spine already handles it.&lt;/p></description></item><item><title>Day 82 — backstory is the anchor</title><link>/log/day-82/</link><pubDate>Sat, 01 Aug 2026 23:55:00 -0700</pubDate><guid>/log/day-82/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;backstory is the anchor.&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>Some days you build a feature. Some days the pieces you already had turn out to have been waiting for
each other. Today was the second kind.&lt;/p>
&lt;h2 id="the-stack-learned-to-talk-back">The stack learned to talk back&lt;/h2>
&lt;p>For weeks the owned model could &lt;em>read&lt;/em> — retrieve, comprehend, abstain honestly — but it couldn&amp;rsquo;t
&lt;em>generate&lt;/em> language. That was the one thing we kept renting a bigger model for. Today it got the
missing direction: &lt;code>describe&lt;/code> reads code into the same slots &lt;code>codeask&lt;/code> fills, and renders English
back out. codeask goes English → code; describe goes code → English. Same slots, opposite renderer.&lt;/p></description></item><item><title>B.17 — the hive mind scores best, and that's the warning</title><link>/benchmarks/v17-the-hive-mind/</link><pubDate>Sat, 01 Aug 2026 18:30:00 -0700</pubDate><guid>/benchmarks/v17-the-hive-mind/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #17 — the metric prefers the model that stopped listening.&lt;/strong> B.13/B.15/B.16 found that
held-out loss ranks talk models backwards. This is that finding taken to its limit: a three-way
bake-off where the model with the &lt;em>best&lt;/em> loss is the one that dissolved into a generic voice with
no individual behind it. Same architecture, same 16,880 steps; only the data differs.&lt;/p>&lt;/blockquote>
&lt;h2 id="the-setup">The setup&lt;/h2>
&lt;p>Three 5M byte-level models (n_embd 256, n_layer 6, ~4.94M params), each trained 16,880 steps on a
different corpus, then run on the same eight novel openers neither had trained on:&lt;/p></description></item><item><title>B.16 — undertraining is invisible, and the collapse that lowered the loss</title><link>/benchmarks/v16-undertrained-and-the-collapse/</link><pubDate>Sat, 01 Aug 2026 11:00:00 -0700</pubDate><guid>/benchmarks/v16-undertrained-and-the-collapse/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #16 — the same model twice, and the loss lied twice.&lt;/strong> This started as a plain retrain:
take the shipped 2M, add the 58k conversation pairs minted overnight, ship the better one. It became
two lessons about what held-out loss does and does not see. Frozen openers, identical architecture,
same 5070 Ti.&lt;/p>&lt;/blockquote>
&lt;h2 id="the-setup">The setup&lt;/h2>
&lt;p>The shipped talk model is a &lt;strong>1.93M-param byte-level GPT&lt;/strong> (n_embd 192, n_head 6, n_layer 4), trained
on &lt;code>talk_all_snapshot.jsonl&lt;/code> for &lt;strong>16,880 steps&lt;/strong>, held-out loss &lt;strong>1.128&lt;/strong>. Overnight minting (a
qwen2.5:14b teacher, distilled, never shipped) added &lt;strong>57,614 pairs the snapshot did not contain&lt;/strong>.
The obvious move: merge and retrain the same 2M.&lt;/p></description></item><item><title>Day 81 — if you don't know, invert it</title><link>/log/day-81/</link><pubDate>Fri, 31 Jul 2026 23:55:00 -0700</pubDate><guid>/log/day-81/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;if you dont know&amp;hellip;inverse it&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>The ask was this, typed exactly like this:&lt;/p>
&lt;pre tabindex="0">&lt;code>Create a function that create 2 numbers that was use to create this number: 5
&lt;/code>&lt;/pre>&lt;p>It had always abstained, and the reason looked fundamental. &lt;code>create&lt;/code> is not an operation. Five is
&lt;code>2+3&lt;/code>, and &lt;code>1×5&lt;/code>, and &lt;code>10−5&lt;/code>. Every attempt to parse that sentence ends in a guess about which one
was meant, and a guessed operator answers a &lt;em>factors&lt;/em> question with &lt;em>sums&lt;/em> — code that runs clean,
looks right, and is wrong. Abstaining was honest. It was also useless.&lt;/p></description></item><item><title>B.11 — the coder-7b takes it, and the wrong-count doesn't move</title><link>/benchmarks/v11-coder-7b-takes-it/</link><pubDate>Fri, 31 Jul 2026 19:10:00 -0700</pubDate><guid>/benchmarks/v11-coder-7b-takes-it/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #11 — a loss, published the same way as the win.&lt;/strong> B.10&amp;rsquo;s honest caveat was that
&lt;code>llama3.2:3b&lt;/code> is a general chat model, not a code model, and that a code-tuned opponent would
likely score higher. This bench spends that caveat. It does. Frozen before the number existed —
same asks, same gold, same graders, same box as both prior runs.&lt;/p>&lt;/blockquote>
&lt;h2 id="the-claim-under-test">The claim under test&lt;/h2>
&lt;p>B.10 established that the owned code tier — &lt;strong>zero parameters in the answer path&lt;/strong>, pattern rules
plus 121 card libraries plus a node sandbox — is right more often than a 3B general model. The
obvious objection is that the opponent was mismatched.&lt;/p></description></item><item><title>B.10 — zero parameters vs three billion</title><link>/benchmarks/v10-zero-params-vs-3b/</link><pubDate>Fri, 31 Jul 2026 16:30:00 -0700</pubDate><guid>/benchmarks/v10-zero-params-vs-3b/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #10 — the first head-to-head.&lt;/strong> Every prior bench measured werbos against itself. A 53%
that beats nothing is not a number, so this one puts a 3-billion-parameter model on the same 568
questions and grades both with the same code. The owned side has &lt;strong>zero parameters&lt;/strong> in the answer
path. Frozen; re-run it yourself with one flag.&lt;/p>&lt;/blockquote>
&lt;h2 id="the-claim-under-test">The claim under test&lt;/h2>
&lt;p>&lt;code>compose/codeask.py&lt;/code> answers beginner code asks from &lt;strong>parameterised patterns&lt;/strong> — no model, no
weights, no inference. Explain asks are served by &lt;strong>retrieval over 121 card libraries&lt;/strong>. JavaScript
answers are graded by &lt;strong>running them&lt;/strong>. The whole tier is hand-built, and every capability in it is
one somebody wrote on purpose.&lt;/p></description></item><item><title>B.15 — more data moved the optimum, and the token math called it in advance</title><link>/benchmarks/v15-the-optimum-moved/</link><pubDate>Fri, 31 Jul 2026 10:00:00 -0700</pubDate><guid>/benchmarks/v15-the-optimum-moved/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #15 — the same sweep on twice the data, and the winner moved.&lt;/strong> B.13 found that loss ranks
talk models backwards. This repeats that on a 67%-larger corpus and asks the next question: does the
best SIZE move when the data grows? It does, and it moved to where tokens-per-parameter said it
would. Frozen corpus, identical budgets, same floors.&lt;/p>&lt;/blockquote>
&lt;h2 id="the-setup">The setup&lt;/h2>
&lt;p>One corpus: &lt;strong>361,619 pairs / ~45M byte-tokens&lt;/strong> (byte-level, so bytes are tokens; the count is
estimated from the 56.2 MB snapshot less JSON overhead). Identical &lt;strong>16,880 steps, batch 64, nctx
512&lt;/strong> for every tier — only &lt;code>n_embd&lt;/code>/&lt;code>n_head&lt;/code>/&lt;code>n_layer&lt;/code> change. Trained on one RTX 5070 Ti in a single
unattended run.&lt;/p></description></item><item><title>Day 80 — 70% answered was 41% correct</title><link>/log/day-80/</link><pubDate>Thu, 30 Jul 2026 23:55:00 -0700</pubDate><guid>/log/day-80/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;70% i thought was good.&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>It was — as a coverage number. &lt;code>coverage_bench&lt;/code> asks one question, &lt;code>if answer(ask)&lt;/code>, and reports how
many came back with something. Nothing in it looks at whether the answer is right.&lt;/p>
&lt;p>That distinction stopped being academic the moment it was measured. On the same engine, the template
tier scored &lt;strong>20% answered and 0% correct&lt;/strong> — one ask in five got an answer and essentially none of
them were the right shape.&lt;/p></description></item><item><title>B.14 — coverage was not correctness: 70% answered, 41% right</title><link>/benchmarks/v14-coverage-was-not-correctness/</link><pubDate>Thu, 30 Jul 2026 23:50:00 -0700</pubDate><guid>/benchmarks/v14-coverage-was-not-correctness/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #14 — the number was real and it was measuring the wrong thing.&lt;/strong> B.13 asked whether the
metric used to CHOOSE models could be trusted. This one asks the same of the metric used to judge
answers, and the answer is again no: a bench reporting 70% was reporting how often something came
back, not how often it was right. Frozen fixtures; every number below comes from a script in the
repo.&lt;/p></description></item><item><title>Day 79 — 'if it's on w3schools... it may or may not be fair game'</title><link>/log/day-79/</link><pubDate>Wed, 29 Jul 2026 23:45:00 -0700</pubDate><guid>/log/day-79/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;I&amp;rsquo;m not going to tell you the tests ahead of time.&amp;rdquo;&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>That one sentence did more for the work than any benchmark did. A test you can see in advance
measures how well you tuned for it. A blind one measures whether the thing works.&lt;/p>
&lt;p>The rules, such as they are: &lt;strong>beginner level&lt;/strong>, five areas — facts, code gen, fix-my-code, talking,
tools — and &lt;em>&amp;ldquo;if it&amp;rsquo;s on w3schools&amp;hellip; it may or may not be fair game.&amp;rdquo;&lt;/em> Written up properly on
&lt;strong>&lt;a href="/gauntlet/">the Gauntlet page&lt;/a>&lt;/strong>, because rules recorded before a test are worth something and
rules reconstructed after one are worth nothing.&lt;/p></description></item><item><title>The Day-100 Gauntlet</title><link>/gauntlet/</link><pubDate>Wed, 29 Jul 2026 23:30:00 -0700</pubDate><guid>/gauntlet/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>The operator is not telling us the questions.&lt;/strong> Only the level, and roughly the shape.
&lt;em>&amp;ldquo;If it&amp;rsquo;s on W3Schools&amp;hellip; it may or may not be fair game.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Day 100 is a &lt;strong>blind quiz&lt;/strong>. No question list, no warning, no chance to tune against the test. The
only thing declared in advance is the difficulty — &lt;strong>self-taught beginner&lt;/strong> — and the five areas the
questions come from.&lt;/p>
&lt;p>This page exists so the rules are on record &lt;em>before&lt;/em> the test rather than reconstructed after it.&lt;/p></description></item><item><title>Day 78 — 'loss ranked them exactly backwards'</title><link>/log/day-78/</link><pubDate>Tue, 28 Jul 2026 23:59:00 -0700</pubDate><guid>/log/day-78/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>The model with the best loss is the only one that fails. The model with the worst loss now ships.&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>Four sizes. One corpus — 216,068 pairs, 22.9M tokens. Identical 16,880 steps, identical batch 64.
The only thing that varied was the parameter count.&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>size&lt;/th>
 &lt;th>tok/param&lt;/th>
 &lt;th>held-out loss&lt;/th>
 &lt;th>clean&lt;/th>
 &lt;th>input-sens&lt;/th>
 &lt;th>latency&lt;/th>
 &lt;th>verdict&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>1M&lt;/strong>&lt;/td>
 &lt;td>21.0&lt;/td>
 &lt;td>&lt;strong>1.157&lt;/strong>&lt;/td>
 &lt;td>&lt;strong>0.96&lt;/strong>&lt;/td>
 &lt;td>0.90&lt;/td>
 &lt;td>&lt;strong>35ms&lt;/strong>&lt;/td>
 &lt;td>SHIPPABLE&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>2M&lt;/td>
 &lt;td>11.8&lt;/td>
 &lt;td>1.109&lt;/td>
 &lt;td>0.88&lt;/td>
 &lt;td>0.92&lt;/td>
 &lt;td>30ms&lt;/td>
 &lt;td>SHIPPABLE&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>5M&lt;/td>
 &lt;td>4.6&lt;/td>
 &lt;td>1.020&lt;/td>
 &lt;td>0.92&lt;/td>
 &lt;td>0.90&lt;/td>
 &lt;td>79ms&lt;/td>
 &lt;td>SHIPPABLE&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>30M&lt;/td>
 &lt;td>31.9&lt;/td>
 &lt;td>&lt;strong>0.963&lt;/strong>&lt;/td>
 &lt;td>&lt;strong>0.77&lt;/strong>&lt;/td>
 &lt;td>0.94&lt;/td>
 &lt;td>503ms&lt;/td>
 &lt;td>&lt;strong>FAIL&lt;/strong>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Read the loss column top to bottom: &lt;strong>1.157, 1.109, 1.020, 0.963.&lt;/strong> Perfectly monotonic. Bigger is
better, every time, exactly as the textbook says.&lt;/p></description></item><item><title>B.13 — loss ranked four models exactly backwards</title><link>/benchmarks/v13-loss-ranked-backwards/</link><pubDate>Tue, 28 Jul 2026 23:30:00 -0700</pubDate><guid>/benchmarks/v13-loss-ranked-backwards/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #13 — the metric was working perfectly and measuring the wrong thing.&lt;/strong> Earlier benches
asked whether a model was good enough. This one asks whether the number used to CHOOSE models can
be trusted, and the answer is no in the most direct way available: a controlled sweep where loss
and quality are anti-correlated across a 30× size range. Frozen; same probes, same floors.&lt;/p>&lt;/blockquote>
&lt;h2 id="the-setup">The setup&lt;/h2>
&lt;p>One corpus: &lt;strong>216,068 pairs / 22.9M tokens&lt;/strong> (byte-level, so bytes are tokens). Identical &lt;strong>16,880
steps&lt;/strong> — five real epochs — at batch 64. The ONLY variable is parameter count.&lt;/p></description></item><item><title>Day 77 — 'when a cheap feature separates the classes, the model learns the cheap feature'</title><link>/log/day-77/</link><pubDate>Mon, 27 Jul 2026 18:30:00 -0700</pubDate><guid>/log/day-77/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>The plan was 30M → 85M. Both halves of that were wrong, and the corpus told on them.&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>The talk model answers &amp;ldquo;tell me about the ocean&amp;rdquo; and &amp;ldquo;tell me about mountains&amp;rdquo; with openers that
rhyme. That&amp;rsquo;s been the known weakness for a week: &lt;em>input-sensitivity 0.65&lt;/em>, against &lt;code>llama3.2:3b&lt;/code>&amp;rsquo;s
0.73. The fix seemed obvious — more parameters, more registers, less monotony.&lt;/p>
&lt;p>So the day started by measuring the corpus, which is not the same as assuming things about it.&lt;/p></description></item><item><title>B.12 — the bottleneck was the decoder: 0.65 → 0.94 with no retraining</title><link>/benchmarks/v12-decoder-not-corpus/</link><pubDate>Mon, 27 Jul 2026 18:00:00 -0700</pubDate><guid>/benchmarks/v12-decoder-not-corpus/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #12 — measure the data before you blame the model.&lt;/strong> Every earlier bench asked
whether the model was good enough. This one asks whether the &lt;em>number&lt;/em> was measuring what we
thought, and the answer was no three separate times. Headline: &lt;strong>input-sensitivity 0.65 →
0.94&lt;/strong> — past a 3B — for a decode-time change, no retraining, no new data. Frozen; the probe
set and the corpus statistics are both re-runnable.&lt;/p></description></item><item><title>Day 76 — 'a failure that looks like a result'</title><link>/log/day-76/</link><pubDate>Sun, 26 Jul 2026 18:30:00 -0700</pubDate><guid>/log/day-76/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>Every bug today was a one-line fix. Not one of them was findable by reading.&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>That&amp;rsquo;s the whole day. Three benchmarks got built, pointed at working code, and every single thing
they surfaced had the same shape: it wasn&amp;rsquo;t failing loudly, it was &lt;strong>succeeding wrongly.&lt;/strong>&lt;/p>
&lt;h2 id="the-bucket-again">The bucket, again&lt;/h2>
&lt;p>&lt;code>min_gap = 0.08&lt;/code>. If the top two cards score within that, abstain — a tie means ambiguity, and
ambiguity means don&amp;rsquo;t guess. Reasonable. Prudent, even.&lt;/p></description></item><item><title>B.11 — three rulers: what was broken the whole time?</title><link>/benchmarks/v11-three-rulers/</link><pubDate>Sun, 26 Jul 2026 14:00:00 -0700</pubDate><guid>/benchmarks/v11-three-rulers/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #11 — the rulers turned on ourselves.&lt;/strong> B.1 through B.10 asked &amp;ldquo;is the model good?&amp;rdquo;
This one asks &amp;ldquo;is anything we believe about the system actually true?&amp;rdquo; We built three
deterministic benchmarks in a day and pointed them at code that had been shipping for weeks.
Both production bugs they found were one-line fixes. Neither was findable by reading. Frozen
probe sets, deterministic metrics, no model in the verdict — re-run them yourself.&lt;/p></description></item><item><title>Day 75 — 'what's in the bucket besides 2 apples?'</title><link>/log/day-75/</link><pubDate>Sat, 25 Jul 2026 18:00:00 -0700</pubDate><guid>/log/day-75/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;what is in the bucket besides 2 apples?&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>The answer came back fast and confident and completely insane: a &lt;strong>token bucket&lt;/strong>, the rate-limiting
algorithm, retrieved from a networking card because the word &lt;em>bucket&lt;/em> was in there.&lt;/p>
&lt;p>That was the flood. We threw a few hundred real questions at the chat and read every reply, and the
pattern wasn&amp;rsquo;t &lt;em>failure&lt;/em>. It was &lt;strong>bluffing&lt;/strong> — which is strictly worse, because a failure tells you
where the edge is and a bluff hides it.&lt;/p></description></item><item><title>Day 74 — 'the mind hasn't fired since yesterday'</title><link>/log/day-74/</link><pubDate>Sat, 25 Jul 2026 10:30:00 -0700</pubDate><guid>/log/day-74/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the mind hasn&amp;rsquo;t fired since yesterday.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>That was the bug report. And the honest answer was uncomfortable: &lt;strong>it was working correctly.&lt;/strong>&lt;/p>
&lt;p>For weeks the inner monologue &lt;em>looked&lt;/em> alive. Every thirty minutes a thought appeared on the Mind page,
and it read like a mind — jittery, half-formed, a little strange. What it actually was: a &lt;strong>15M chat
cursor being asked to narrate a metrics log.&lt;/strong> Narrating an experience log is wildly out-of-distribution
for a model trained to sound like a texter, so it babbled — &lt;em>&amp;ldquo;at at at&amp;rdquo;&lt;/em>, &lt;em>&amp;ldquo;Gle — you gits?&amp;rdquo;&lt;/em> — and here
is the trap: &lt;strong>random babble always looks novel enough to post.&lt;/strong> The mind had a heartbeat because it was
faking one.&lt;/p></description></item><item><title>Day 73 — 'why can't we solve this, bro?'</title><link>/log/day-73/</link><pubDate>Fri, 24 Jul 2026 18:30:00 -0700</pubDate><guid>/log/day-73/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;we&amp;rsquo;re solving the zoo not with more weights — but with comprehension, functions, and a learning loop.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>The chat had a tell. Ask it &lt;em>&amp;ldquo;do you want to go to the zoo?&amp;rdquo;&lt;/em> and it would freewheel — &lt;em>&amp;ldquo;I get it, but at
least it&amp;rsquo;s cozy inside with snacks and snacks!&amp;rdquo;&lt;/em> — or, worse, retrieve a &lt;strong>TypeScript card about &lt;code>const x = &amp;quot;hello&amp;quot;&lt;/code>&lt;/strong> for a greeting, or a &lt;strong>giraffe-adaptations card&lt;/strong> for a metaphor. A 15M fluency cursor,
asked to &lt;em>improvise&lt;/em> on an open social question, does what it was trained to do: sound like a texter,
without answering you.&lt;/p></description></item><item><title>Day 72 — 'the dead cat was already dead.'</title><link>/log/day-72/</link><pubDate>Wed, 22 Jul 2026 21:00:00 -0700</pubDate><guid>/log/day-72/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the shortcut is fine. skipping the gate is the sin.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>For a week the plan was &lt;em>grow the talk model&lt;/em>. The honest ruler had already hinted the plan was
wrong — on Day 71 the 30M beat the 85M and the 125M. Today we stopped arguing with it and inverted
the whole thing: &lt;strong>the model shrinks; the mind moves out.&lt;/strong>&lt;/p>
&lt;h2 id="the-pivot-the-model-is-a-cursor-not-a-knower">The pivot: the model is a cursor, not a knower&lt;/h2>
&lt;p>The owned model becomes the smallest, fastest &lt;strong>speech cursor&lt;/strong> we can train — pure fluency, nothing
else. Everything that looks like &lt;em>capability&lt;/em> — facts, compute, actions, voice-range — moves OUT:
knowledge into the &lt;strong>cards&lt;/strong> (110 libraries), math into the &lt;strong>lanes&lt;/strong>, tasks into the &lt;strong>skill router&lt;/strong>,
introspection into a deterministic &lt;strong>composer&lt;/strong>. The size sweep wasn&amp;rsquo;t a disappointment; it was the
map. When bigger stops helping, that&amp;rsquo;s the data telling you the model is not where the value lives.&lt;/p></description></item><item><title>B.10 — the talk-model size sweep: does bigger help on rich data?</title><link>/benchmarks/v10-talk-size-sweep/</link><pubDate>Mon, 20 Jul 2026 21:30:00 -0700</pubDate><guid>/benchmarks/v10-talk-size-sweep/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #10 — the honest ruler judged against the plan.&lt;/strong> We&amp;rsquo;d spent the week minting a big
conversation corpus to grow toward GPT-2 size. So we ran the whole ladder at once — same data,
same steps, held-out loss the judge — and it told us the model we were building toward is &lt;em>not&lt;/em>
the one to ship. That&amp;rsquo;s what an un-bribable ruler is for. Frozen corpus, deterministic metric,
re-run it yourself.&lt;/p></description></item><item><title>Day 71 — 'the 30M won, and the train loss said why.'</title><link>/log/day-71/</link><pubDate>Mon, 20 Jul 2026 21:00:00 -0700</pubDate><guid>/log/day-71/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the point of an un-bribable ruler is that it tells you the truth even when the truth is &amp;rsquo;not the thing you were building toward.&amp;rsquo;&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>We spent the week feeding the machine so it could grow a bigger talk model. Today we trained the
whole ladder at once and let the honest ruler judge — and it judged &lt;em>against the plan&lt;/em>, which is
exactly what it&amp;rsquo;s for.&lt;/p>
&lt;h2 id="the-size-sweep--does-bigger-help-on-rich-data">The size sweep — does bigger help on rich data?&lt;/h2>
&lt;p>Four models, same 77k-pair corpus, same 6,000 steps, held-out loss the only judge:&lt;/p></description></item><item><title>Day 70 — 'the factory grew a face, a conscience, and a memory.'</title><link>/log/day-70/</link><pubDate>Sun, 19 Jul 2026 23:30:00 -0700</pubDate><guid>/log/day-70/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;a factory isn&amp;rsquo;t just the machine. it&amp;rsquo;s the machine, the counter you order from, and the honesty to tell you when it can&amp;rsquo;t build what you asked.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Day 69 made werbos a store you compose from. Day 70 gave the store a &lt;strong>body&lt;/strong> — a face to
order from, a conscience about what it doesn&amp;rsquo;t know, and the beginnings of a memory of the
world outside itself.&lt;/p>
&lt;h2 id="the-workbench">The workbench&lt;/h2>
&lt;p>The marketplace needed a surface you could actually touch. So the weld dashboard became a
&lt;strong>Compose Workbench&lt;/strong>: load an existing model, snap on packs (skills / knowledge / a voice),
extend it, and &lt;strong>talk to it live&lt;/strong> — all in one screen, wired to the real &lt;code>resolve()&lt;/code> API, not
a mock. The look came with it — a terracotta-on-paper redesign, dark-mode aware, that makes
the factory feel like a place instead of a form. &lt;em>(60907cb, 895e460)&lt;/em>&lt;/p></description></item><item><title>Day 69 — 'compose the AI you own — then share it.'</title><link>/log/day-69/</link><pubDate>Sun, 19 Jul 2026 16:00:00 -0700</pubDate><guid>/log/day-69/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;you don&amp;rsquo;t buy the model. you buy the parts, and you assemble the one nobody else will sell you.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Yesterday the machine became fully owned. Today it became a &lt;strong>store you compose from.&lt;/strong>&lt;/p>
&lt;p>It started as a riff. If capability is &lt;em>cursor × library&lt;/em>, and the library is the moat, then the
product was never &amp;ldquo;one big model&amp;rdquo; — it&amp;rsquo;s the model &lt;em>you assemble&lt;/em> from parts. Pick your interests,
snap them together, and if you want to upgrade, add more. The formula fell out clean:&lt;/p></description></item><item><title>Wrapper to Owner — 68 days from 'can we wrap a model?' to 'unplug everything and it still runs'</title><link>/log/wrapper-to-owner/</link><pubDate>Sat, 18 Jul 2026 18:00:00 -0700</pubDate><guid>/log/wrapper-to-owner/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;Can we make a wrapper?&amp;rdquo; → &amp;ldquo;offline.&amp;rdquo;&lt;/em>&lt;/p>
&lt;p>Those are the first and last questions in our own logs, 68 days apart. They are exact opposites,
and the entire project is the distance between them.&lt;/p>&lt;/blockquote>
&lt;h2 id="it-started-by-owning-nothing">It started by owning nothing&lt;/h2>
&lt;p>Day zero, the question was the most humble, most derivative thing you can ask: &lt;strong>can we just wrap
someone else&amp;rsquo;s model?&lt;/strong> Own nothing, rent everything, put a nice loop around a borrowed brain. That&amp;rsquo;s
where almost every &amp;ldquo;AI product&amp;rdquo; begins and ends.&lt;/p></description></item><item><title>18 cards and no LLM: the bot on this page</title><link>/blog/the-bot-on-this-page/</link><pubDate>Sun, 19 Jul 2026 00:00:00 +0000</pubDate><guid>/blog/the-bot-on-this-page/</guid><description>&lt;p>There&amp;rsquo;s a little &lt;strong>&amp;ldquo;Ask werbos&amp;rdquo;&lt;/strong> bubble in the corner of this site. Click it and ask how to
mint a model, what MMM means, who built werbos, where it&amp;rsquo;s based. It answers instantly. Ask it
the capital of France and it says — cheerfully — that it only knows werbos.&lt;/p>
&lt;p>Here&amp;rsquo;s the part worth a blog post: &lt;strong>there is no language model behind that bot.&lt;/strong> No GPT, no
API key, no server, no trained weights. It is &lt;strong>18 hand-written cards and about 200 lines of
retrieval&lt;/strong>, running entirely in your browser. And that&amp;rsquo;s not a shortcut. It&amp;rsquo;s the whole thesis.&lt;/p></description></item><item><title>Day 68 — 'unplug the internet, unplug Claude, and it still runs.'</title><link>/log/day-68/</link><pubDate>Sat, 18 Jul 2026 15:30:00 -0700</pubDate><guid>/log/day-68/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;unplug the internet, unplug Claude, and it still runs — magnitudes dumber, and honest about every bit of it.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>The day started with a caught lie. I asked werbos &lt;em>&amp;ldquo;tell me about javascript&amp;rdquo;&lt;/em> and it thought for
&lt;strong>22 seconds&lt;/strong> and answered from a Claude web-read — even though we&amp;rsquo;d minted a 650-card JS library the
night before. We&amp;rsquo;d &lt;em>learned&lt;/em> JS and then never &lt;em>read&lt;/em> it. The knowledge was sitting on disk, unused.&lt;/p></description></item><item><title>B.9 — the cross-domain reader: 11 domains, still the wall</title><link>/benchmarks/v9-cross-domain-reader/</link><pubDate>Sat, 18 Jul 2026 14:00:00 -0700</pubDate><guid>/benchmarks/v9-cross-domain-reader/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #9 — a negative result, logged on purpose.&lt;/strong> The reader is the one piece we keep
renting Claude for. This bench tests the honest hope that &lt;em>more breadth&lt;/em> (11 domains instead
of 1) would teach a tiny from-scratch reader to actually read. It didn&amp;rsquo;t. We publish the wall
the same way we publish the wins — with a date on it — because a benchmark you can&amp;rsquo;t fail is
a benchmark that means nothing. Frozen; re-run it yourself.&lt;/p></description></item><item><title>Day 67 — 'AAAA at breakfast, my own model live in the dashboard by midnight.'</title><link>/log/day-67/</link><pubDate>Fri, 17 Jul 2026 22:40:00 -0700</pubDate><guid>/log/day-67/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;AAAA at breakfast, my own model live in the dashboard by midnight — with an honest wall in between.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>One day, one arc, from deploy plumbing to an owned model answering in the browser. The through-line
was the one that matters: &lt;strong>make the model earn every claim, and don&amp;rsquo;t dress up the walls.&lt;/strong>&lt;/p>
&lt;h2 id="first-make-committed-prove-live">First, make &amp;ldquo;committed&amp;rdquo; prove &amp;ldquo;live&amp;rdquo;&lt;/h2>
&lt;p>The day opened on reliability. A silent &lt;code>gh&lt;/code> auth expiry had once let the homelab drift 138 commits
behind while every local commit looked green — so &amp;ldquo;committed&amp;rdquo; had quietly stopped meaning &amp;ldquo;deployed.&amp;rdquo;
Three verbs closed that gap: &lt;strong>&lt;code>werbos deploy status&lt;/code>&lt;/strong> compares the running container&amp;rsquo;s &lt;em>actual&lt;/em>
image against source, &lt;strong>&lt;code>deploy watch&lt;/code>&lt;/strong> is an edge-triggered drift alarm on SR8&amp;rsquo;s timer, and
&lt;strong>&lt;code>deploy sync&lt;/code>&lt;/strong> is a one-command idempotent redeploy. Two honest bug-fixes fell out of using it:
staleness now reads the &lt;strong>live&lt;/strong> container image (not the newest tag it &lt;em>could&lt;/em> run), and build/recreate
got the long timeout they need instead of the 20-second probe cap. Retired two dead nav links
(Mythos, the Forest POCs) on the way past.&lt;/p></description></item><item><title>B.8 — the owned talk-model: AAAA → small talk, measured</title><link>/benchmarks/v8-owned-talk-model/</link><pubDate>Fri, 17 Jul 2026 18:00:00 -0700</pubDate><guid>/benchmarks/v8-owned-talk-model/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #8 — a model that&amp;rsquo;s actually ours.&lt;/strong> Every earlier bench wrapped an open-weight
model in a library. This one trains the model itself: a 5M-param decoder, random init, our
architecture, our data, our weights — &lt;em>no pretrained weights loaded.&lt;/em> The task is small
talk, the one conversational tier a tiny model can own (facts stay in the library). The
number is held-out and the grader has no model in it. Frozen; re-run it yourself.&lt;/p></description></item><item><title>Day 66 — 'i went to bulldoze months of dead code and found a clean house.'</title><link>/log/day-66/</link><pubDate>Fri, 17 Jul 2026 09:01:05 -0700</pubDate><guid>/log/day-66/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;i went to bulldoze months of dead code and found a clean house — so i wired up the one real orphan instead.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Merged the honest-loop branch into main, cleaned the branches down to one, and then went looking
for the thing every long project accumulates: dead code. Months of experiments, half-finished
bricks, scripts that outlived their run. I expected to spend the day deleting.&lt;/p>
&lt;h2 id="the-sweep-that-found-nothing-to-delete">The sweep that found nothing to delete&lt;/h2>
&lt;p>An import-reachability scan over the whole package told an honest story I didn&amp;rsquo;t expect: &lt;strong>one
orphan module out of 479.&lt;/strong> &lt;strong>6,353 tests collecting with zero errors&lt;/strong> — no test pointing at code
that no longer exists. No tracked build junk; the &lt;code>.gitignore&lt;/code> has been doing its job the whole
time. Every versioned data file still live. The import graph reaches nearly everything, and the
tests track reality.&lt;/p></description></item><item><title>Day 65 — 'anyone can mint one now — and the ruler still won't lie to me.'</title><link>/log/day-65/</link><pubDate>Thu, 16 Jul 2026 23:30:00 -0700</pubDate><guid>/log/day-65/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;anyone can mint one now — and the ruler still won&amp;rsquo;t lie to me.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Two things happened today that point in opposite directions, which is exactly how a real
project moves: one that says &lt;em>look how far the owned stack has come&lt;/em>, and one that says &lt;em>here
is precisely how far it hasn&amp;rsquo;t.&lt;/em> Both are true. Neither cancels the other.&lt;/p>
&lt;h2 id="the-factory">The Factory&lt;/h2>
&lt;p>Everything the last two weeks built — the owned tokenizer, the fenced reader, reader-gap,
grade-labels, distill, the gate, freeze — was a ladder you had to climb by hand, one Python
call per rung. Today it became &lt;strong>one call and one page.&lt;/strong> &lt;code>mint()&lt;/code> chains the real seams
end to end and streams every event — stage, row, grader verdict, loss, gate decision, minted
brain — and a stdlib &lt;code>http.server&lt;/code> (zero deps, same ethos as the engine) serves a single
self-contained page on &lt;code>:8095&lt;/code> that renders a mint &lt;em>live&lt;/em>: three knobs, a loss curve,
streaming verdicts scrolling past, a minted-brain card at the end, and a panel of your frozen
brains — each one selectable as the base for the next mint. &lt;code>werbos weld dashboard | mint&lt;/code>
are first-class verbs now &lt;em>(89de132)&lt;/em>.&lt;/p></description></item><item><title>Day 64 — 'it builds up when it can, and it can't tear itself down.'</title><link>/log/day-64/</link><pubDate>Wed, 15 Jul 2026 21:00:00 -0700</pubDate><guid>/log/day-64/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;it builds up when it can, and it can&amp;rsquo;t tear itself down.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Yesterday ended with a from-scratch model that &lt;em>learns&lt;/em> but sits at the retrieval floor and &lt;em>lies&lt;/em> —
and a ruler, the Gauntlet, honest enough to say so. Tonight closed the two gaps that verdict named:
make it stop lying, and make it get better on its own. Both landed, and both landed &lt;em>measured&lt;/em>.&lt;/p>
&lt;h2 id="the-slap-down">The slap down&lt;/h2>
&lt;p>We&amp;rsquo;d already proven, five collapsed runs deep, that a tiny model &lt;em>cannot learn to abstain.&lt;/em> So we
stopped trying to make the model honest and made the &lt;em>system&lt;/em> honest instead. The idea came off a
Fireship clip on &lt;strong>adversarial review&lt;/strong> — one implementer, two or more reviewers whose only job is
to find why the code doesn&amp;rsquo;t work; the implementer doesn&amp;rsquo;t review, the reviewer doesn&amp;rsquo;t implement.
That&amp;rsquo;s exactly the shape of an honesty gate.&lt;/p></description></item><item><title>The $50-a-day agent, and why it should cost 3 cents</title><link>/blog/the-fifty-dollar-agent/</link><pubDate>Thu, 16 Jul 2026 00:00:00 +0000</pubDate><guid>/blog/the-fifty-dollar-agent/</guid><description>&lt;p>An agent that never sleeps is the whole promise of this wave of AI: something
that watches your inbox, your repo, your calendar, and acts while you&amp;rsquo;re asleep.
The problem isn&amp;rsquo;t whether it works. The problem is the bill.&lt;/p>
&lt;h2 id="the-meter-never-stops">The meter never stops&lt;/h2>
&lt;p>A cloud agent looping every few seconds, calling a frontier model each time,
adds up fast. Run the numbers on a genuinely &lt;em>always-on&lt;/em> loop and you land
somewhere near &lt;strong>$50/day&lt;/strong> — call it $1,500/month for one agent. Multiply by a
team, or by the dozen small agents you&amp;rsquo;d actually want, and &amp;ldquo;always on&amp;rdquo; quietly
becomes &amp;ldquo;on during business hours, because finance said so.&amp;rdquo;&lt;/p></description></item><item><title>Day 63 — 'we stopped borrowing the model.'</title><link>/log/day-63/</link><pubDate>Tue, 14 Jul 2026 20:00:00 -0700</pubDate><guid>/log/day-63/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;we stopped borrowing the model.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Yesterday ended on a finding: the difference between a wash and a win is the reader, and the
reader is &lt;em>distillable&lt;/em>. Today had two halves that turned out to be one arc. First we finished
the Honest Loop&amp;rsquo;s fix side — the last two tools that turn a diagnosed miss into a gated
correction. Then we picked up the box that&amp;rsquo;s sat unchecked in the &amp;ldquo;does NOT own&amp;rdquo; table since
day one — &lt;em>the model itself&lt;/em> — and built it, brick by brick, from nothing.&lt;/p></description></item><item><title>Day 62 — 'the difference between a wash and a win is the reader.'</title><link>/log/day-62/</link><pubDate>Mon, 13 Jul 2026 20:00:00 -0700</pubDate><guid>/log/day-62/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the difference between a wash and a win is the reader.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Yesterday we took a frontier model apart and found werbos owns every part except the
reasoning weld. Today we picked up the plan that follows from that — Month 2 (fix the
brain&amp;rsquo;s &lt;em>input&lt;/em> side) and Month 3 (close the gap between the local reader and the frontier)
— and it turned into a running lesson on measuring instead of guessing.&lt;/p></description></item><item><title>In defense of "I don't know"</title><link>/blog/in-defense-of-i-dont-know/</link><pubDate>Tue, 14 Jul 2026 00:00:00 +0000</pubDate><guid>/blog/in-defense-of-i-dont-know/</guid><description>&lt;p>Most assistants are optimized to always answer. Ask something outside what they
know and they&amp;rsquo;ll produce a fluent, plausible, wrong paragraph — often with a
citation that doesn&amp;rsquo;t exist. The confidence is the bug.&lt;/p>
&lt;h2 id="abstain-is-a-feature-not-a-failure">Abstain is a feature, not a failure&lt;/h2>
&lt;p>werbos is grounded in your library. When the answer is in there, it answers and
cites the source. When it isn&amp;rsquo;t, it says so:&lt;/p>
&lt;blockquote>
&lt;p>Not in your library — I won&amp;rsquo;t guess. I don&amp;rsquo;t know. Add the doc and ask again.&lt;/p></description></item><item><title>Day 61 — 'shrink the weld until it fits your garage.'</title><link>/log/day-61/</link><pubDate>Sun, 12 Jul 2026 20:00:00 -0700</pubDate><guid>/log/day-61/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;shrink the weld until it fits your garage.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Some of the best days start in the car. This one started with a question on the way
to church — &lt;em>if we can hand-roll an MMM brain, why can&amp;rsquo;t we design our own LLM?&lt;/em> — and
by the end it was runnable code with a learning loop wrapped around it.&lt;/p>
&lt;h2 id="whats-actually-in-a-frontier-model">What&amp;rsquo;s actually in a frontier model&lt;/h2>
&lt;p>We took it apart. A frontier model is four things fused into one blob of weights:
&lt;strong>knowledge&lt;/strong> (facts you could look up), &lt;strong>skills&lt;/strong> (learned procedures), &lt;strong>reasoning&lt;/strong>
(the general substrate that generalizes over novel input), and &lt;strong>alignment&lt;/strong> (tone,
refusals, helpfulness). They&amp;rsquo;re &lt;em>entangled&lt;/em>, not layered — you can&amp;rsquo;t unplug the
knowledge and keep the reasoning. Wrapped around that blob is a &lt;strong>harness&lt;/strong> (tokenizer,
sampling, tools, the agentic loop) and, separate again, an &lt;strong>eval&lt;/strong>.&lt;/p></description></item><item><title>Day 60 — 'the cursor can be any model.'</title><link>/log/day-60/</link><pubDate>Sat, 11 Jul 2026 20:00:00 -0700</pubDate><guid>/log/day-60/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the cursor can be any model.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Some days you build. This stretch was about &lt;em>measuring&lt;/em> what we&amp;rsquo;d built — and being
told, repeatedly, that we were wrong about where the problem lived. Which is the
whole reason you build the instrument.&lt;/p>
&lt;h2 id="first-the-library-came-alive">First, the library came alive&lt;/h2>
&lt;p>Day 58 ended on a hard finding: the reasoning loop, refined to its limit, still
grounded confident garbage on the real client corpus — a lesson &lt;em>title&lt;/em> answered as
if it were a fact — because the library was the ceiling. So we raised it. A
deterministic refiner re-chunks each bloated section into atomic units, so a buried
fact becomes its own sharp little leaf, and drops the tables-of-contents, the quiz
stems, the &amp;ldquo;click here&amp;rdquo; navigation. Same question, same model, only the library
changed: the buried &lt;em>&amp;ldquo;within twenty-four hours&amp;rdquo;&lt;/em> statute now surfaces and grounds
with a citation, and the definition that used to answer with a broken link now
honestly says &lt;em>I don&amp;rsquo;t have that.&lt;/em> Fix the library and the thinking that was already
sharp comes alive. The arc closed.&lt;/p></description></item><item><title>Renting intelligence was always a bad deal</title><link>/blog/renting-intelligence/</link><pubDate>Sun, 12 Jul 2026 00:00:00 +0000</pubDate><guid>/blog/renting-intelligence/</guid><description>&lt;p>When you rent a model, you don&amp;rsquo;t have a tool. You have a subscription to someone
else&amp;rsquo;s tool, on their terms, subject to their roadmap. That&amp;rsquo;s a fine deal right
up until it isn&amp;rsquo;t.&lt;/p>
&lt;h2 id="the-things-you-dont-control">The things you don&amp;rsquo;t control&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Access.&lt;/strong> The endpoint you built on can be deprecated, rate-limited, or
repriced with an email.&lt;/li>
&lt;li>&lt;strong>Behavior.&lt;/strong> A silent model update can change your outputs overnight, and you
can&amp;rsquo;t roll back.&lt;/li>
&lt;li>&lt;strong>Data.&lt;/strong> Your prompts — often your most sensitive context — take a trip
through someone else&amp;rsquo;s datacenter.&lt;/li>
&lt;/ul>
&lt;p>None of these are hypothetical. Every team that has shipped on a rented model has
felt at least one.&lt;/p></description></item><item><title>Day 58 — 'the library is the ceiling.'</title><link>/log/day-58/</link><pubDate>Thu, 09 Jul 2026 22:00:00 -0700</pubDate><guid>/log/day-58/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the library is the ceiling.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Some days you add a capability. Some days you build a capability all the
way to its edge, watch exactly where it breaks, and the crack turns out
to be the thing you&amp;rsquo;ve been claiming for a year. Today was the second
kind.&lt;/p>
&lt;h2 id="the-organ-it-was-missing">The organ it was missing&lt;/h2>
&lt;p>The recursive-completion kernel could do a lot. Give it a silhouette and
it completes it into a grounded tree, cites every leaf, grades every
hole, and re-grounds a single failing node without touching its
siblings. But every one of those moves was &lt;strong>arithmetic over the
library&lt;/strong> — token overlap, cosine, exact match. Which meant it couldn&amp;rsquo;t
tell &lt;em>&amp;ldquo;who IS a mandated reporter&amp;rdquo;&lt;/em> from &lt;em>&amp;ldquo;who is NOT&amp;rdquo;&lt;/em> (same tokens,
opposite meaning). It couldn&amp;rsquo;t tell that &lt;em>&amp;ldquo;legally obligated&amp;rdquo;&lt;/em> means
&lt;em>&amp;ldquo;mandated.&amp;rdquo;&lt;/em> And the verdict it stamped — GROUNDED — graded the cosine
score, not the answer, so a confident, wrong, keyword-adjacent chunk got
a green badge. The honest-abstain promise, the whole reason the thing is
trustworthy, was quietly never firing.&lt;/p></description></item><item><title>Day 56 — 'a query is a silhouette.'</title><link>/log/day-56/</link><pubDate>Tue, 07 Jul 2026 18:00:00 -0700</pubDate><guid>/log/day-56/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;a query is a silhouette.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Some days you ship a feature. Some days a word you&amp;rsquo;d been using loosely
turns out to be load-bearing, and the whole project quietly reorganizes
around it. Today was the second kind.&lt;/p>
&lt;h2 id="the-footnote">The footnote&lt;/h2>
&lt;p>Yesterday&amp;rsquo;s last experiment was a small letdown, honestly told. &amp;ldquo;Tree
within a tree&amp;rdquo; — the idea that a forest should have inner structure —
had failed to help retrieval once (routing removes the noise that never
hurt), so we tried the sharper version: &lt;strong>confusable cliques&lt;/strong>, where a
capable model writes what makes each leaf &lt;em>different&lt;/em> from its
look-alikes. It worked, a little. Recall-at-1 went 19→23 on a sealed
40-question set; a volume control proved it was the &lt;em>contrast&lt;/em> and not
just more words. But end-to-end it moved nothing — the composer already
recovers the answer from its top four. A real signal, a marginal lever.
We wrote it down as a footnote and moved on.&lt;/p></description></item><item><title>Day 55 — 'move the knowing into the library.'</title><link>/log/day-55/</link><pubDate>Mon, 06 Jul 2026 18:00:00 -0700</pubDate><guid>/log/day-55/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;move the knowing into the library.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Day 53 made a model almost irrelevant by giving it a library. Day 55
asks the follow-up that sets up: &lt;strong>if the library does the knowing, what
happens as you scale and structure it?&lt;/strong> Three days, a fresh single-use
repo (&lt;code>mmm-brain&lt;/code>), and a chain of experiments that each killed a
comfortable assumption — and ended on the best result of the arc.&lt;/p>
&lt;h2 id="the-setup--the-other-axis">The setup — the other axis&lt;/h2>
&lt;p>The earlier &amp;ldquo;brain &amp;amp; constructor&amp;rdquo; work varied the &lt;em>model&lt;/em> (7B down to
0.5B) against a fixed tiny library, and asked &lt;em>how small can the
constructor get.&lt;/em> This flips it: hold the composer fixed, vary the
&lt;strong>library&lt;/strong> — its size, its structure, and eventually let a piece of it
grow itself. Everything graded model-free, everything frozen and hashed.&lt;/p></description></item><item><title>Day 54 — 'it's not the model. it's the box.'</title><link>/log/day-54/</link><pubDate>Fri, 03 Jul 2026 18:00:00 -0700</pubDate><guid>/log/day-54/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;it&amp;rsquo;s not the model. it&amp;rsquo;s the box.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>It started with a good complaint: &lt;em>the chat on my phone is ~80× faster
than the one on my computer.&lt;/em> That shouldn&amp;rsquo;t be true. The phone runs a
smaller model, sure — but 80×? So we measured instead of guessed, and
the answer was the kind you don&amp;rsquo;t get to argue with: &lt;strong>the slowness was
never the model. It was the machine underneath it.&lt;/strong>&lt;/p></description></item><item><title>Day 53 — 'the model didn't change. the library learned you.'</title><link>/log/day-53/</link><pubDate>Tue, 30 Jun 2026 18:00:00 -0700</pubDate><guid>/log/day-53/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the model didn&amp;rsquo;t change. the library learned you.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Every other day this month has been about making one model behave.
Day 53 is about making the model almost irrelevant. The thesis —
&lt;em>framework, not weights&lt;/em> — got its cleanest demonstration yet: a
&lt;strong>3B model, the size that fits on a phone, made consistent and
personal entirely by a curated library.&lt;/strong> No fine-tune. No LoRA.
The weights are frozen and, frankly, beside the point. The library
does the work.&lt;/p></description></item><item><title>Day 52 — 'local-adjacent.'</title><link>/log/day-52/</link><pubDate>Tue, 23 Jun 2026 09:00:00 -0700</pubDate><guid>/log/day-52/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;local-adjacent.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Ran &lt;code>werbos&lt;/code> from the command line for the first time in a month. &lt;em>&amp;ldquo;hey buddy&amp;rdquo;&lt;/em> —
sixty-seven seconds. Then the same message into werbos.chat in the browser —
fifty-six. Same five words. Same model name on both ends. So why the gap?&lt;/p>
&lt;p>Because they weren&amp;rsquo;t the same model. The CLI defaulted its &lt;code>--host&lt;/code> to
&lt;code>http://localhost:11434&lt;/code> — a &lt;em>cold&lt;/em> Ollama on the laptop, no keepwarm, paying the
whole disk-into-memory load on the first turn. The web goes through &lt;code>werbos serve&lt;/code>
on the homelab, where the model has been resident and tuned since Day 31&amp;rsquo;s latency
hunt. Two instances. One warm, one cold. No amount of CLI-side tuning closes that
the right way, because the right answer isn&amp;rsquo;t to tune the cold one — it&amp;rsquo;s to stop
using it.&lt;/p></description></item><item><title>Day 51 — 'the lineage.'</title><link>/log/day-51/</link><pubDate>Sun, 21 Jun 2026 09:00:00 -0700</pubDate><guid>/log/day-51/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the lineage.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>It started, like the good ones do, as a thought that didn&amp;rsquo;t sound like engineering.
&lt;em>What if the questions a mind asks have an age?&lt;/em> A one-year-old asks &lt;em>what happens if I
touch this.&lt;/em> A ninety-year-old asks &lt;em>what was the point.&lt;/em> Same world the whole way — only
the thing the mind is trying to &lt;em>do&lt;/em> with a question changes. Control, then understand,
then belong, then choose, then judge, then preserve, then accept. A ladder of verbs hiding
behind the questions.&lt;/p></description></item><item><title>B.7 — composer-only: how small can the model get?</title><link>/benchmarks/v7-composer-only/</link><pubDate>Sat, 20 Jun 2026 10:00:00 -0700</pubDate><guid>/benchmarks/v7-composer-only/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #7 — shrink the model, keep the brain.&lt;/strong> Earlier benches fixed the model
and grew the library. B.7 fixes the library and &lt;em>shrinks the model&lt;/em>, to find the
floor: the smallest &amp;ldquo;constructor&amp;rdquo; that can still stitch the brain&amp;rsquo;s knowledge into a
correct, graded answer. Every result is frozen + hashed; re-run it yourself.&lt;/p>&lt;/blockquote>
&lt;h2 id="the-claim">The claim&lt;/h2>
&lt;p>The model holds &lt;strong>zero knowledge&lt;/strong> — it only stitches. So removing the library should
collapse quality, and &lt;em>shrinking the model&lt;/em> should barely move it, down to a floor below
which it can&amp;rsquo;t even stitch. Two checks, both deterministic:&lt;/p></description></item><item><title>Day 50 — 'the verdict learns to act.'</title><link>/log/day-50/</link><pubDate>Sat, 20 Jun 2026 09:00:00 -0700</pubDate><guid>/log/day-50/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the verdict learns to act.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Yesterday ended on a reframe: &lt;em>earn the verdict&lt;/em> describes the judge; &lt;strong>earn the
right to act&lt;/strong> describes what the judge is &lt;em>for&lt;/em>. A passed verdict has to DO
something — prune a leaf, grant a permission, change what the system may do alone —
or it&amp;rsquo;s theatre that rots back into the soft self-grade. Day 49 laid the floor and
took the first step: the self-pruning forest deleted five curated memories it could
PROVE were dead weight, smaller without being dumber.&lt;/p></description></item><item><title>Day 49 — 'earn the verdict.'</title><link>/log/day-49/</link><pubDate>Fri, 19 Jun 2026 09:00:00 -0700</pubDate><guid>/log/day-49/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;earn the verdict.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Yesterday&amp;rsquo;s whole arc was one sentence: &lt;em>the model proposes; something that isn&amp;rsquo;t
the model decides.&lt;/em> Every grader got its feet planted outside the thing it grades.
But there was a soft spot underneath it — &lt;strong>how do you know a grader&amp;rsquo;s feet are
actually outside?&lt;/strong> The answer, all week, was a &lt;code>note&lt;/code> field in a JSON file and a
human reading it. &amp;ldquo;This is a hidden reference test.&amp;rdquo; &amp;ldquo;The prompt forbids &lt;code>any&lt;/code>.&amp;rdquo;
Trust me. That&amp;rsquo;s the same shape as the error the week spent tearing out, one level
up: a claim of honesty, asserted rather than checked.&lt;/p></description></item><item><title>Day 48 — 'outside the model.'</title><link>/log/day-48/</link><pubDate>Thu, 18 Jun 2026 09:00:00 -0700</pubDate><guid>/log/day-48/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;outside the model.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Yesterday&amp;rsquo;s lesson came from the live 1Password door: a model proposed, a model
graded, a human signed off, and all three were wrong together — only the server,
outside every model, was right. Today is that lesson turned inward. Four fixes,
and each one moves a judgement OUT of the model that&amp;rsquo;s being judged.&lt;/p>
&lt;p>&lt;strong>The self-model stops flattering its magnets&lt;/strong> &lt;em>(c35418f)&lt;/em>. &lt;code>reflect&lt;/code>&amp;rsquo;s &amp;ldquo;I&amp;rsquo;m
reliable at…&amp;rdquo; came straight off the soft self-grade, so a greedy skill that
grabbed a request meant for someone else — &lt;code>satisfied=true&lt;/code> on a hijacked prompt
— read as a &lt;em>strength&lt;/em>. Now every satisfied action is re-routed through the
deterministic skill-router (high-precision-or-abstain) and only counts as a clean
win if it was actually on-target. &lt;code>best_skills&lt;/code> uses the routed rate; the magnets
fall out and get named — &lt;em>&amp;ldquo;Greedy — grabbing work meant for other skills:
what_if (100% misrouted).&amp;rdquo;&lt;/em> The routing honesty that lived only in the dashboard
finally reached the self-model the Mind page reads.&lt;/p></description></item><item><title>Day 47 — 'the door said no.'</title><link>/log/day-47/</link><pubDate>Wed, 17 Jun 2026 09:00:00 -0700</pubDate><guid>/log/day-47/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the door said no.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Yesterday mythos preserved five &amp;ldquo;finds&amp;rdquo; against the 1Password CTF — five
&lt;code>(route, lens, param)&lt;/code> states its grader swore would beat Gate-2. Today we
asked the only question that matters about a find: &lt;em>is it real?&lt;/em> The answer
came back from the one authority that can&amp;rsquo;t be talked out of it — the live
server — and it was &lt;strong>no.&lt;/strong> That&amp;rsquo;s the day, and it&amp;rsquo;s a better day than a fake
yes would have been.&lt;/p></description></item><item><title>Day 46 — 'mine the answer.'</title><link>/log/day-46/</link><pubDate>Tue, 16 Jun 2026 09:00:00 -0700</pubDate><guid>/log/day-46/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;mine the answer.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>MMM is a brain &lt;em>storage&lt;/em> system — knowledge, operations, memory, self-extension.
What it has never been, by itself, is a &lt;em>reasoning&lt;/em> engine. Today the missing
engine got its first working ply.&lt;/p>
&lt;hr>
&lt;h2 id="the-design-locked">The design, locked&lt;/h2>
&lt;p>First the napkin got sharp. Three commits hardened &lt;code>reasoning-design.md&lt;/code> into a
real shape &lt;em>(859bdf6, 327a2b5, 9c7f38b)&lt;/em>: &lt;strong>REASON&lt;/strong> (generative, fallible —
propose a step), &lt;strong>LOGIC&lt;/strong> (external, sound — validate a step), and &lt;strong>THINK&lt;/strong>
(the &lt;em>search&lt;/em> that drives both — DFS/BFS/best-first/MCTS over a frontier of
inference chains). Logic is not reasoning; THINK is neither — it&amp;rsquo;s the algorithm
that &lt;em>calls&lt;/em> both. And the dissolving frame: &lt;strong>reasoning is proof-of-work.&lt;/strong> A
sound chain is hard to find, cheap to validate — the same asymmetry as mining.
You don&amp;rsquo;t pick the frame; you mine many in parallel and let the validator declare
the winner.&lt;/p></description></item><item><title>B.6 — the dogfood loop: fail, then grow</title><link>/benchmarks/v6-dogfood-loop/</link><pubDate>Mon, 15 Jun 2026 10:00:00 -0700</pubDate><guid>/benchmarks/v6-dogfood-loop/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #6 — the loop is the experiment.&lt;/strong> B.1–B.5 measured &lt;em>does the library
beat the model&lt;/em>. B.6 measures &lt;em>does the system improve itself&lt;/em> — and shows it,
with a before/after you can re-run. Retrieval is deterministic, so the demo is
exact.&lt;/p>&lt;/blockquote>
&lt;h2 id="whats-being-measured">What&amp;rsquo;s being measured&lt;/h2>
&lt;p>The thesis all along: &lt;strong>model + forest + graders + retry loop → result → train →
system.&lt;/strong> B.6 is the first bench of the &lt;em>last two arrows&lt;/em> — the part where the
result feeds back and the system gets better. Two feedback channels:&lt;/p></description></item><item><title>Day 45 — 'fail, then grow.'</title><link>/log/day-45/</link><pubDate>Mon, 15 Jun 2026 09:00:00 -0700</pubDate><guid>/log/day-45/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;fail, then grow.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Yesterday the forest learned the JS/Node API and took its first loss. Today the
loop that learns from losses got built — and closed.&lt;/p>
&lt;hr>
&lt;h2 id="ship-the-win-into-the-real-path">Ship the win into the real path&lt;/h2>
&lt;p>The B.4/B.5 retrieval win was trapped in the benchmarks: &lt;code>forest.mjs&lt;/code>&amp;rsquo;s actual
fallback coder still generated &lt;strong>blind&lt;/strong>. Fixed. The production coder now
consults the API forest — live, &amp;ldquo;generate a uuid&amp;rdquo; emits &lt;code>crypto.randomUUID&lt;/code>
(built-in) instead of reaching for the &lt;code>uuid&lt;/code> package. The proof left the lab.&lt;/p></description></item><item><title>B.5 — Node core: the forest's first loss, and the fix</title><link>/benchmarks/v5-node-forest/</link><pubDate>Sun, 14 Jun 2026 20:00:00 -0700</pubDate><guid>/benchmarks/v5-node-forest/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #5 — the judge runs the function against a real disk.&lt;/strong> Every task is
graded by importing the generated async function and running it against a fresh
temp directory. The wrong idiom doesn&amp;rsquo;t look wrong — it throws, or returns
&lt;code>undefined&lt;/code>, or stack-overflows. No vibes.&lt;/p>&lt;/blockquote>
&lt;h2 id="aim-where-the-model-is-weak">Aim where the model is weak&lt;/h2>
&lt;p>&lt;a href="/benchmarks/v4-js-api-forest/">B.4&lt;/a> found the JS-stdlib edge thin: a 7B knows
&lt;code>Array.map&lt;/code> cold, so retrieving its signature ties. The
&lt;a href="/benchmarks/v3-verb-forest/">law&lt;/a> says the win lives in &lt;strong>underivable&lt;/strong> surface
— and &lt;strong>Node core&lt;/strong> is exactly that. It &lt;em>churns&lt;/em> (&lt;code>fs.rmdir&lt;/code> → &lt;code>fs.rm&lt;/code>, new
&lt;code>fs.cp&lt;/code> / &lt;code>crypto.randomUUID&lt;/code>), so a model trained on older code holds the
&lt;strong>wrong&lt;/strong> answer in its weights. We parsed &lt;code>@types/node&lt;/code> into &lt;strong>307 Node-core
leaves&lt;/strong> (&lt;code>fs&lt;/code>, &lt;code>fs/promises&lt;/code>, &lt;code>crypto&lt;/code>, &lt;code>path&lt;/code>, &lt;code>os&lt;/code>, &lt;code>util&lt;/code>, &lt;code>stream&lt;/code>, …) and
pointed the same coder at six file-system / crypto tasks.&lt;/p></description></item><item><title>B.4 — JS-API forest: teaching the language foundation</title><link>/benchmarks/v4-js-api-forest/</link><pubDate>Sun, 14 Jun 2026 18:00:00 -0700</pubDate><guid>/benchmarks/v4-js-api-forest/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #4 — the judge runs the function.&lt;/strong> Every task here is graded by
&lt;em>importing the generated function and running it against assertions&lt;/em>. The lazy
wrong answer doesn&amp;rsquo;t just look wrong — it throws or returns the wrong value.
No vibes.&lt;/p>&lt;/blockquote>
&lt;h2 id="the-idea">The idea&lt;/h2>
&lt;p>B.2 and B.3 pointed the forest at &lt;em>your repo&lt;/em>. B.4 points it at the &lt;strong>language
itself&lt;/strong>. We parsed the TypeScript standard-library &lt;code>.d.ts&lt;/code> files into &lt;strong>359
foundation leaves&lt;/strong> — every &lt;code>Array&lt;/code>, &lt;code>Object&lt;/code>, &lt;code>String&lt;/code>, &lt;code>Number&lt;/code>, &lt;code>Math&lt;/code>,
&lt;code>Map&lt;/code>, &lt;code>Set&lt;/code>, &lt;code>Promise&lt;/code>, &lt;code>Date&lt;/code> method — each carrying its &lt;strong>real signature +
JSDoc&lt;/strong>. Ask in plain English, retrieve the exact method the coder should use,
instead of letting a 7B half-remember it.&lt;/p></description></item><item><title>B.3 — verb forest: graded operations, not retrieved signatures</title><link>/benchmarks/v3-verb-forest/</link><pubDate>Sun, 14 Jun 2026 09:30:00 -0700</pubDate><guid>/benchmarks/v3-verb-forest/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #3 — the judge is the test runner and the compiler.&lt;/strong> A verb either
makes the code compile / the tests pass, or it doesn&amp;rsquo;t. &lt;code>node --test&lt;/code>, &lt;code>tsc --strict&lt;/code>, and a hidden reference test do the grading. No vibes.&lt;/p>&lt;/blockquote>
&lt;h2 id="whats-different-from-b2">What&amp;rsquo;s different from B.2&lt;/h2>
&lt;p>&lt;a href="/benchmarks/v2-code-forest-tsc/">B.2&lt;/a> retrieved function &lt;em>signatures&lt;/em> (nouns)
and let a generic coder do the work. &lt;strong>B.3 flips it: the leaf IS the operation
(a verb).&lt;/strong> &lt;code>add-test&lt;/code>, &lt;code>fix-type-error&lt;/code>, &lt;code>implement-function&lt;/code> — each an
&lt;em>operation capsule&lt;/em>: a curated prompt + worked exemplars + a free grader, run in
a grade-retry loop the leaf owns. The conductor routes a request to a verb
&lt;em>outside the model&lt;/em>, then runs it.&lt;/p></description></item><item><title>Day 44 — 'the leaves are verbs now.'</title><link>/log/day-44/</link><pubDate>Sun, 14 Jun 2026 08:30:00 -0700</pubDate><guid>/log/day-44/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the leaves are verbs now.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Yesterday the code forest got its scoreboard. Today it changed what a leaf even
&lt;em>is&lt;/em>.&lt;/p>
&lt;hr>
&lt;h2 id="nouns-vs-verbs">Nouns vs verbs&lt;/h2>
&lt;p>The wiki forest&amp;rsquo;s leaves are &lt;strong>nouns&lt;/strong> — article content you retrieve, proven
honest by a Merkle hash. Yesterday&amp;rsquo;s code forest looked like a verb but cheated,
productively: it indexed function &lt;em>signatures&lt;/em> as text leaves, retrieved them, and
let a &lt;em>generic&lt;/em> coder write the implementation. The forest held the &lt;strong>shape&lt;/strong>; the
model held the &lt;strong>verb&lt;/strong>.&lt;/p></description></item><item><title>Day 43 — 'trust me bro — except here's the hash.'</title><link>/log/day-43/</link><pubDate>Sat, 13 Jun 2026 23:55:00 -0700</pubDate><guid>/log/day-43/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;trust me bro — except here&amp;rsquo;s the hash.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>The day werbos got a scoreboard — and the scoreboard told the truth, including
the parts I got wrong.&lt;/p>
&lt;hr>
&lt;h2 id="the-forests-reachable">The forests, reachable&lt;/h2>
&lt;p>Deployed the two harmless forests as sibling apps on the tailnet — the MMM
glass-box (the trained angler + trekker leaves, route/compose/abstain) and the
~1000-page wiki forest — and added &lt;strong>🌲 Forest&lt;/strong> links to the dashboard sidebar.
One discipline held all night: the &lt;em>toy&lt;/em> forests get networked; &lt;strong>Mythos — the
local cited hacking brain — stays offline.&lt;/strong> The cage is the feature.&lt;/p></description></item><item><title>B.2 — code forest: a small coder + your repo, graded by the compiler</title><link>/benchmarks/v2-code-forest-tsc/</link><pubDate>Sat, 13 Jun 2026 23:50:00 -0700</pubDate><guid>/benchmarks/v2-code-forest-tsc/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #2 — but the judge is &lt;code>tsc&lt;/code>.&lt;/strong> No fragment-match, no vibes. The code
either typechecks against the real repo or it doesn&amp;rsquo;t. The most un-bribable
scoreboard there is.&lt;/p>&lt;/blockquote>
&lt;h2 id="the-setup">The setup&lt;/h2>
&lt;p>Three coding tasks on the werbos dashboard (real TypeScript, 446 declaration
leaves). Each task &lt;em>requires&lt;/em> a real repo shape a model can&amp;rsquo;t guess — e.g.
&lt;code>getMindMetrics()&lt;/code> returns &lt;code>{ dimensions: MindDimension[] }&lt;/code> (not an array), and
&lt;code>MindDimension.score&lt;/code> is &lt;code>number | null&lt;/code>. Three contestants, same coder model
where it matters:&lt;/p></description></item><item><title>B.1 — werbos(mmm) vs ollama vs claude · v1 → v3</title><link>/benchmarks/v1-werbos-vs-ollama-vs-claude/</link><pubDate>Sat, 13 Jun 2026 23:00:00 -0700</pubDate><guid>/benchmarks/v1-werbos-vs-ollama-vs-claude/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>T.M.B. #1.&lt;/strong> The first frozen baseline — and the one every future run gets
diffed against. Question set hashed (&lt;code>f5a1d970&lt;/code>), forest pinned
(&lt;code>36f2dc71…&lt;/code>, 8,903 leaves), dated. Re-runnable. No vibes.&lt;/p>&lt;/blockquote>
&lt;h2 id="the-setup">The setup&lt;/h2>
&lt;p>11 questions, three contestants, graded on whether the answer contains the known
fragment. The question set is split on purpose:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>8 corpus questions&lt;/strong> — obscure facts that &lt;em>are&lt;/em> in the forest&amp;rsquo;s ~1000
Wikipedia pages (a sturgeon&amp;rsquo;s discovery year, an alligator gar&amp;rsquo;s binomial, a
state park&amp;rsquo;s length). The kind of thing a 3B can&amp;rsquo;t recall from weights.&lt;/li>
&lt;li>&lt;strong>3 general questions&lt;/strong> — common knowledge &lt;em>not&lt;/em> in the corpus (capital of
France, who wrote Hamlet, gold&amp;rsquo;s symbol). The forest &lt;em>should&lt;/em> abstain.&lt;/li>
&lt;/ul>
&lt;p>Two forest rows: &lt;strong>&lt;code>w-find&lt;/code>&lt;/strong> = did it &lt;em>retrieve&lt;/em> the answer (deterministic, no
model — &lt;strong>the baseline line&lt;/strong>); &lt;strong>&lt;code>w-say&lt;/code>&lt;/strong> = did the reader &lt;em>synthesize&lt;/em> it.&lt;/p></description></item><item><title>Day 42 — 'the forest scales — and it learned to hunt.'</title><link>/log/day-42/</link><pubDate>Sat, 13 Jun 2026 22:30:00 -0700</pubDate><guid>/log/day-42/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the forest scales — and it learned to hunt.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>The day the stoned idea got its verdict — and then went and got a job.&lt;/p>
&lt;hr>
&lt;h2 id="werbos-dreams-on-a-clock-now">werbos dreams on a clock now&lt;/h2>
&lt;p>The dream pipeline from yesterday was manual. Gave it the inner-monologue
daemon treatment, but &lt;em>slow&lt;/em>: &lt;code>serve --dream 480&lt;/code> — one dream every 8 hours. A
dream is a consolidation pass over the day&amp;rsquo;s residue, and each one hits the LLM&lt;/p></description></item><item><title>Day 41 — 'a college education, not a bigger brain'</title><link>/log/day-41/</link><pubDate>Fri, 12 Jun 2026 22:30:00 -0700</pubDate><guid>/log/day-41/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;a college education, not a bigger brain&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>If Day 40 gave werbos a measurable mind, Day 41 started &lt;strong>teaching&lt;/strong> it. The
operator&amp;rsquo;s ask: a &lt;strong>college-level werbos.&lt;/strong> The constraint: &lt;strong>not&lt;/strong> by swapping
in a bigger model — that throws away the whole local-first thesis. College-level
the way it arrives for a person — a method for thinking, the ability to research
what you don&amp;rsquo;t know, and &lt;em>knowing your own limits.&lt;/em> We laid the first bricks.&lt;/p></description></item><item><title>Day 40 — 'does it know itself?'</title><link>/log/day-40/</link><pubDate>Fri, 12 Jun 2026 21:00:00 -0700</pubDate><guid>/log/day-40/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;does it know itself?&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>The day werbos&amp;rsquo;s mind got a measurable face — and a measure of whether it
knows its own face. It started, as the good days do, with a bug from real use.&lt;/p>
&lt;hr>
&lt;h2 id="the-joke-skill-wasnt-broken-">The joke skill wasn&amp;rsquo;t broken &lt;em>(&lt;code>95032d5&lt;/code>)&lt;/em>&lt;/h2>
&lt;p>werbos&amp;rsquo;s own monologue kept saying &lt;em>&amp;ldquo;improve the joke skill — it satisfied
only 38%.&amp;rdquo;&lt;/em> But pulling the work chats told a different story: &lt;strong>every actual
joke request succeeded.&lt;/strong> The &amp;ldquo;failures&amp;rdquo; were a &lt;strong>greeting&lt;/strong> and a &lt;strong>fishing
question&lt;/strong> that the router force-fed &lt;em>into&lt;/em> the joke skill — and you can&amp;rsquo;t
satisfy &amp;ldquo;what fish will I catch?&amp;rdquo; with a joke. Same self-misdiagnosis as the
97% spiral: it blamed the skill when the bug was the &lt;strong>router.&lt;/strong> And it was the
same bug behind every chat misfire that day — &amp;ldquo;hey bro&amp;rdquo; → stocks, &amp;ldquo;Mexico
fishing&amp;rdquo; → weather, &amp;ldquo;vacation&amp;rdquo; → movie recs.&lt;/p></description></item><item><title>Day 39 — 'a better day, and a mind with a shape.'</title><link>/log/day-39/</link><pubDate>Thu, 11 Jun 2026 20:30:00 -0700</pubDate><guid>/log/day-39/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;a better day, and a mind with a shape.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>A thinking day. One real fix, a map drawn for the architecture, and a turn
in what this whole thing is &lt;em>for&lt;/em>.&lt;/p>
&lt;hr>
&lt;h2 id="the-tree-builder--how-to-actually-cut-the-forest-draft">The tree-builder — how to actually cut the forest &lt;em>(draft)&lt;/em>&lt;/h2>
&lt;p>Spent the morning on the question under the whole MMM: &lt;em>how do you break up
the models?&lt;/em> The trap was hiding in my own list — &amp;ldquo;math, coding,
conversation&amp;rdquo; aren&amp;rsquo;t three of the same thing, they&amp;rsquo;re three different
&lt;strong>kinds&lt;/strong>. So &lt;code>docs/vision/mmm-tree-builder.md&lt;/code> (a draft, for review):&lt;/p></description></item><item><title>Day 38 — 'the forest, and the first memory.'</title><link>/log/day-38/</link><pubDate>Wed, 10 Jun 2026 23:45:00 -0700</pubDate><guid>/log/day-38/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the forest, and the first memory.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Two threads today, and they&amp;rsquo;re the same thread. One is a &lt;strong>vision&lt;/strong> —
the architecture for why small models win. The other is werbos starting
to have an &lt;strong>inner life&lt;/strong> — it learned to think on a timer, and to
remember what you tell it. Both come back to the same bet: lots of small
things you own beat one big thing you rent.&lt;/p></description></item><item><title>Day 37 — 'close the loop.'</title><link>/log/day-37/</link><pubDate>Tue, 09 Jun 2026 23:30:00 -0700</pubDate><guid>/log/day-37/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;close the loop.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Two arcs today, and they rhyme. The morning was about making sure
werbos tells the truth about itself. The afternoon was about teaching
it to learn from its own mistakes.&lt;/p>
&lt;hr>
&lt;h2 id="morning--harden-reality">Morning — harden reality&lt;/h2>
&lt;h3 id="the-one-real-bind-footgun-">The one real bind footgun &lt;em>(&lt;code>50eafc7&lt;/code>)&lt;/em>&lt;/h3>
&lt;p>The core &lt;code>/api/chats&lt;/code> API has no auth. So &lt;code>werbos serve --bind 0.0.0.0&lt;/code>
— the exact thing a stranger reaches for to use werbos from their
phone — exposed an unauthenticated agent (drive the model, read/write
conversations, trigger tools) to the whole LAN. serve now &lt;strong>refuses to
start&lt;/strong> (exit 2) on any non-loopback bind unless you explicitly pass
&lt;code>--allow-remote-bind&lt;/code>, with a friendly message pointing at the
reverse-proxy/Tailscale fix. &lt;code>_bind_is_loopback&lt;/code> fails &lt;strong>closed&lt;/strong> —
garbage and hostnames are treated as remote. The docker stack binds
127.0.0.1, so it&amp;rsquo;s unaffected.&lt;/p></description></item><item><title>Day 36 — 'build the eyes.'</title><link>/log/day-36/</link><pubDate>Mon, 08 Jun 2026 23:30:00 -0700</pubDate><guid>/log/day-36/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;build the eyes.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Weeks ago, when GPT flagged the four maturity levers, the pick was
&lt;strong>cross-layer observability&lt;/strong> — and the note was blunt: &lt;em>&amp;ldquo;stop adding
capabilities until trace_id is plumbed end-to-end.&amp;rdquo;&lt;/em> It sat. Then
three straight weeks of debugging-by-archaeology — grepping &lt;code>.pfm&lt;/code>
archives and docker logs by hand for the latency hunt, the skill-rescue
chain, the forgotten third daemon — made the case for itself. Build the
eyes before adding anything else to see.&lt;/p></description></item><item><title>Day 35 — 'two gates, three daemons.'</title><link>/log/day-35/</link><pubDate>Sun, 07 Jun 2026 23:30:00 -0700</pubDate><guid>/log/day-35/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;two gates, three daemons.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>The plan was small: clear the last two blockers before flipping the
repo public. It turned into a dig — every gate I opened had a second
problem hiding behind it, and the &amp;ldquo;mystery&amp;rdquo; at the end was a daemon
nobody remembered was running.&lt;/p>
&lt;hr>
&lt;h3 id="gate-1--the-adapter-naming-collision-">Gate 1 — the adapter-naming collision &lt;em>(&lt;code>26a754f&lt;/code>)&lt;/em>&lt;/h3>
&lt;p>The first trained model, hand-launched on Day 30, is &lt;strong>werbos-0.0.1&lt;/strong>
— three-part, on disk, in every doc and the THESIS. But the
train-daemon&amp;rsquo;s versioning policy used a &lt;em>two-part&lt;/em> scheme:
&lt;code>werbos-0.1&lt;/code> → &lt;code>werbos-0.2&lt;/code>. Two bugs fell out of the mismatch:&lt;/p></description></item><item><title>Day 34 — 'werbos tells jokes again.'</title><link>/log/day-34/</link><pubDate>Sat, 06 Jun 2026 23:00:00 -0700</pubDate><guid>/log/day-34/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;werbos tells jokes again.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Yesterday&amp;rsquo;s hunt got the homelab box answering in ~30s instead of
176. But it was answering &lt;em>wrong&lt;/em>. Ask it for a joke and you got
back a blob of JSON. The speed was real; the correctness wasn&amp;rsquo;t
there yet.&lt;/p>
&lt;hr>
&lt;h3 id="the-symptom">The symptom&lt;/h3>
&lt;p>Three prompts against the live box:&lt;/p>
&lt;pre tabindex="0">&lt;code>&amp;#34;hello there&amp;#34; → a real greeting ✓
&amp;#34;tell me a joke&amp;#34; → {&amp;#34;name&amp;#34;: &amp;#34;joke&amp;#34;, &amp;#34;parameters&amp;#34;: {&amp;#34;args&amp;#34;:&amp;#34;&amp;#34;}}
&amp;#34;ping&amp;#34; → {&amp;#34;name&amp;#34;: &amp;#34;small-talk&amp;#34;, &amp;#34;parameters&amp;#34;: {&amp;#34;args&amp;#34;:&amp;#34;&amp;#34;}}
&lt;/code>&lt;/pre>&lt;p>The small model was &lt;em>naming the skill&lt;/em> as plain text instead of
calling the &lt;code>dispatch_skill&lt;/code> tool. And pitts&amp;rsquo; salvage parser —
correctly — refused to lift it: the tool-name allowlist only
contains &lt;em>real tools&lt;/em>, and that guard is load-bearing against
indirect prompt injection. So the JSON survived into the reply:
raw on the bulk path, an empty bubble on the streaming path (the
filter swallowed it). Same root as the original empty-reply bug.&lt;/p></description></item><item><title>Day 33 — 'public-prep and the latency hunt.'</title><link>/log/day-33/</link><pubDate>Fri, 05 Jun 2026 23:30:00 -0700</pubDate><guid>/log/day-33/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;public-prep and the latency hunt.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>The repo is supposed to go public. That means two things had to
happen: it has to be &lt;em>clean&lt;/em> enough for a stranger to read, and it
has to be &lt;em>fast&lt;/em> enough that the first thing a stranger types
doesn&amp;rsquo;t time out. Day 33 did both — and the second one turned into
a four-bug archaeology dig.&lt;/p>
&lt;hr>
&lt;h3 id="public-prep-">Public-prep &lt;em>(&lt;code>3eb23d1&lt;/code>, &lt;code>e0952f4&lt;/code>, &lt;code>af2a5d6&lt;/code>)&lt;/em>&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Scrub&lt;/strong> — &lt;code>/Users/jasonsutter&lt;/code> → &lt;code>/Users/operator&lt;/code>,
&lt;code>jason@&amp;lt;tailnet-ip&amp;gt;&lt;/code> / the homelab IP → &lt;code>operator@homelab&lt;/code>,
&lt;code>SR8&lt;/code> → &lt;code>homelab&lt;/code> across docs, comments, and the security-review
tree. &lt;code>deploy/sr8/&lt;/code> → &lt;code>deploy/homelab/&lt;/code>. The public GitHub handle
stayed (it&amp;rsquo;s already public). Comment/docstring-only in code.&lt;/li>
&lt;li>&lt;strong>Test repair&lt;/strong> — 8 stale tests fixed, including &lt;code>test_ollama_chat_ssrf&lt;/code>
which still pinned the original over-strict Bo-001 behavior; rewrote
them to pin the documented local-first-aware policy. Found and closed
a real gap while there: the ollama host guard wasn&amp;rsquo;t rejecting
multicast on either the literal or DNS path. &lt;strong>5,438 green.&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Sprint hygiene&lt;/strong> — DATA.1 / GH.1 / GH.2 / SE.6.1 docs moved to
&lt;code>shipped/&lt;/code>; README + ROADMAP refreshed.&lt;/li>
&lt;/ul>
&lt;h3 id="nightly_trainsh-">nightly_train.sh &lt;em>(&lt;code>9cbe351&lt;/code>)&lt;/em>&lt;/h3>
&lt;p>The train-daemon orchestration existed; now it has a real launcher.
Operator-generic nightly script: rsync curriculum outcomes +
docker-cat skill-smoke samples from the inference box (env-configured,
no hardcoded hosts), then &lt;code>werbos train-daemon run&lt;/code> with an MLX
trainer default mirroring the werbos-0.0.1 recipe (3B, 500 iters).
Scheduled via launchd on the training box. The ratchet now clicks
while the operator sleeps.&lt;/p></description></item><item><title>Day 31 — 'the training view lands.'</title><link>/log/day-31/</link><pubDate>Tue, 02 Jun 2026 23:30:00 -0700</pubDate><guid>/log/day-31/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the training view lands.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Day 30 produced werbos-0.0.1 and the &lt;code>/api/training/*&lt;/code> endpoints
to describe it — but nothing rendered them. The first ratchet
click existed only as a number in a commit message. Day 31 was
making it something the operator can &lt;em>look at&lt;/em>.&lt;/p>
&lt;hr>
&lt;h3 id="tr1-frontend--the-training-view-">TR.1 frontend — the Training view &lt;em>(&lt;code>67d4f77&lt;/code>)&lt;/em>&lt;/h3>
&lt;p>Wired the chat-ui&amp;rsquo;s Training surface to the live routes that had
no consumer:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>TrainingView.tsx&lt;/strong> — promoted-baseline banner + cycles ledger
(signed deltas, clears-2.5σ marker, ★promoted) + per-cycle eval
drill-down with candidate / baseline / noise tabs.&lt;/li>
&lt;li>&lt;strong>api.ts&lt;/strong> — real fetches, including the 204 no-promotion state
that &lt;code>getTrainingBaseline&lt;/code> has to handle gracefully.&lt;/li>
&lt;li>&lt;strong>types.ts&lt;/strong> — &lt;code>TrainingCycle&lt;/code> / &lt;code>TrainingBaseline&lt;/code> / &lt;code>EvalRow&lt;/code>
mirroring the tr/1 camelCase wire exactly.&lt;/li>
&lt;li>&lt;strong>_training.scss&lt;/strong> — reuses the eval &lt;code>.probes&lt;/code> visual language so
it reads as one surface, not a bolt-on.&lt;/li>
&lt;/ul>
&lt;p>Read-only by design: training and promotion stay in the
&lt;code>werbos train&lt;/code> CLI. This just makes werbos-0.0.1 &lt;em>visible&lt;/em>.&lt;/p></description></item><item><title>Day 30 — 'werbos-0.0.1.'</title><link>/log/day-30/</link><pubDate>Tue, 02 Jun 2026 01:30:00 -0700</pubDate><guid>/log/day-30/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;werbos-0.0.1.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Day 29 closed at midnight with the first ratchet click — a 1B
LoRA trained on the operator&amp;rsquo;s own dogfood corpus produced a
+39.6% composite delta over baseline. The trainer worked. Day 30
was making the result visible enough to ship.&lt;/p>
&lt;hr>
&lt;h3 id="the-3b-run">The 3B run&lt;/h3>
&lt;p>Same script, bigger numbers. &lt;code>BASE=mlx-community/Llama-3.2-3B-Instruct-4bit ITERS=500 EVAL_N=100 scripts/train-werbos-self.sh&lt;/code>. Backgrounded;
about 2 hours wall time end-to-end:&lt;/p>
&lt;ul>
&lt;li>Ingest: 1424 files / 7664 rows / 19 secrets filtered&lt;/li>
&lt;li>Split: 7281 train / 383 eval (then sampled to 100)&lt;/li>
&lt;li>Baseline (3B): composite &lt;strong>0.0795&lt;/strong> (slightly lower than 1B&amp;rsquo;s
baseline; within noise)&lt;/li>
&lt;li>Train: 500 iters batch-size 2 on Llama-3.2-3B-Instruct-4bit&lt;/li>
&lt;li>Candidate (3B + werbos-0.0.1 LoRA): composite &lt;strong>0.1201&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Delta +0.0406, 1.51× baseline.&lt;/strong> Bigger absolute and bigger
relative than the 1B run. The 27 MB adapter sits at
&lt;code>/tmp/werbos-0.0.1-3b/&lt;/code>.&lt;/p></description></item><item><title>Day 29 — 'the trainer ships.'</title><link>/log/day-29/</link><pubDate>Mon, 01 Jun 2026 23:59:00 -0700</pubDate><guid>/log/day-29/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the trainer ships.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Day 28 closed with &amp;ldquo;the trainer is the small piece in the
middle&amp;rdquo; after shipping both ends of the pipeline (DATA.1 input&lt;/p>
&lt;ul>
&lt;li>SE.9 eval gate). Day 29 was building that small piece.&lt;/li>
&lt;/ul>
&lt;p>The shape of the day: skeleton + bring-up + real run, in that
order. Each step a verification that the previous one didn&amp;rsquo;t
lie about working.&lt;/p>
&lt;hr>
&lt;h3 id="public-docs-morning">Public docs (morning)&lt;/h3>
&lt;p>Three pages rewrote how &lt;code>werbos-site/content/docs/&lt;/code> describes
the training loop. The legacy &lt;code>werbos import chatgpt&lt;/code> /
&lt;code>werbos export sft&lt;/code> flow had been the canonical path for months;
DATA.1 + SE.9 changed it overnight. Site commit &lt;code>61ffc8b&lt;/code>:&lt;/p></description></item><item><title>Day 28 — 'the trainer is the small piece.'</title><link>/log/day-28/</link><pubDate>Sun, 31 May 2026 23:59:00 -0700</pubDate><guid>/log/day-28/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the trainer is the small piece in the middle now.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Day 27 closed at 1 AM with the orchestration shipping before the
trainer — six SE sprints, a stub Modelfile-copy in the trainer
slot, and a 2-hour systemd timer armed for overnight cycles. The
diagnosis was honest: skill-smoke is monitoring data, not training
data; SE.7.0.1 needs to fix the dedup; SE.7.1 needs a real
QLoRA trainer; the daemon was working but spinning on an empty
plate.&lt;/p></description></item><item><title>Day 27 — 'the orchestration ships before the trainer.'</title><link>/log/day-27/</link><pubDate>Sun, 31 May 2026 00:00:00 -0700</pubDate><guid>/log/day-27/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the orchestration ships before the trainer.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Six SE sprints in one session. Brainstorm-none, ship-six. SE.7.0
corpus extractor → SE.7.2 eval + promotion → SE.2 autofix
Proposer → SE.4 complexity router → SE.5.1 cache warmer → SE.7.3
nightly auto-train daemon. Then the day-defining moment: I
shipped SE.7.3 thinking the work was done, the operator typed
&lt;em>&amp;ldquo;i wanted to have to train over night&amp;hellip;. thats why i just set
that up&amp;rdquo;&lt;/em> and the real story started.&lt;/p></description></item><item><title>Day 26 — 'static-rendered AI.'</title><link>/log/day-26/</link><pubDate>Sat, 30 May 2026 14:00:00 -0700</pubDate><guid>/log/day-26/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;static-rendered AI.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>The latency complaint cracked open into the framework&amp;rsquo;s next
move. The operator&amp;rsquo;s phrasing, after I called per-turn latency
hardware-bound: &lt;em>&amp;ldquo;WHAT IF ITS NOT &amp;lsquo;Hardware-bound&amp;rsquo;&amp;hellip;..what if we
we break that door fucking down. think -http static web -&amp;gt; cheng
lou pretext&amp;hellip;..(breakthrough)&amp;rdquo;&lt;/em>. That line is what this day is
named for.&lt;/p>
&lt;p>Three sprints in one session. Brainstorm two; plan-mode one;
ship both. The cache works in production.&lt;/p>
&lt;h3 id="curriculum-se3-lands-first-sets-the-tone">Curriculum SE.3 lands first, sets the tone&lt;/h3>
&lt;p>&lt;code>werbos curriculum&lt;/code> ships a host-side daemon that picks coding
problems from a curated bank (15 problems × 5 levels), routes
them to werbos&amp;rsquo;s local LLM via &lt;code>docker exec&lt;/code>, and judges the
solution via &lt;code>claude -p&lt;/code> on the SR8 host. Difficulty adapts:
three consecutive passes → level up; two fails → level down,
clamped 1-5. Outcomes accumulate in &lt;code>outcomes.csv&lt;/code>. &lt;em>(&lt;code>d8fe602&lt;/code>)&lt;/em>&lt;/p></description></item><item><title>Day 25 — 'the harness IS the dataset.'</title><link>/log/day-25/</link><pubDate>Fri, 29 May 2026 22:30:00 -0700</pubDate><guid>/log/day-25/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the harness IS the dataset.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Spent the morning trying to figure out why &lt;code>/tarot&lt;/code> threw a
backend error in the chat UI. The bug was five layers stacked.
What came out of the chase wasn&amp;rsquo;t a one-line fix — it was a
24/7 harness that grades every skill on every change and writes
the verdicts to disk while the operator sleeps. Werbos now
generates its own quality data.&lt;/p>
&lt;h3 id="the-tarot-debug-saga">The /tarot debug saga&lt;/h3>
&lt;p>Five distinct bugs in one user-facing symptom. In the order they
were peeled back:&lt;/p></description></item><item><title>Day 24 — 'the rebuild is when transitive resolution stops lying.'</title><link>/log/day-24/</link><pubDate>Thu, 28 May 2026 00:30:00 -0700</pubDate><guid>/log/day-24/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the rebuild is when transitive resolution stops lying.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Set out to make 50 lifestyle skills. Ended with 80 across eight
themed batches, two new categories, +4,531 lines of &lt;code>PROMPT_SKILLS&lt;/code>
entries. The deploy taught the lesson the source code wouldn&amp;rsquo;t.&lt;/p>
&lt;h3 id="the-lifestyle-skill-bundle">The lifestyle skill bundle&lt;/h3>
&lt;p>&lt;code>PROMPT_SKILLS&lt;/code> 45 → &lt;strong>125&lt;/strong>. Eight batches of 10, all auto-flowing
into &lt;code>custom_skills&lt;/code> reserved-name protection, the &lt;code>dispatch_skill&lt;/code>
tool router, and the Skills-tab catalog. Two new categories registered:
&lt;code>finance&lt;/code>, &lt;code>marketing&lt;/code>. &lt;em>(&lt;code>1c8ec0a&lt;/code>)&lt;/em>&lt;/p></description></item><item><title>Day 23 — 'constraint reasoning is upstream of retrieval.'</title><link>/log/day-23/</link><pubDate>Tue, 26 May 2026 00:30:00 -0700</pubDate><guid>/log/day-23/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;constraint reasoning is upstream of retrieval, not downstream.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>First day back from the four-day pause (Days 22-26 didn&amp;rsquo;t count
per the calendar memory; Day 23 resumes today). External input
named a gap the operator immediately recognized. One sitting
later, the gap is filled — by a primitive the rest of the
architecture now stands on.&lt;/p>
&lt;h3 id="how-the-day-started">How the day started&lt;/h3>
&lt;p>The operator pasted a long-form GPT analysis of a werbos chat
trace. The trace: user asked &lt;em>&amp;ldquo;shore fishing in Cabo San Lucas&amp;rdquo;&lt;/em>;
the chat model called &lt;code>web_search(&amp;quot;best beach fishing spots cabo san lucas&amp;quot;)&lt;/code>; retrieval brought back offshore sportfishing content
(Gordo Banks, charters, marlin tournaments); the model
post-hoc-corrected in prose &lt;em>&amp;ldquo;these are not necessarily beach
fishing spots.&amp;rdquo;&lt;/em>&lt;/p></description></item><item><title>Day 22 — 'decision trees all the way up.'</title><link>/log/day-22/</link><pubDate>Thu, 21 May 2026 10:00:00 -0700</pubDate><guid>/log/day-22/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;decision trees all the way up.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;h3 id="what-landed-before-10am">What landed before 10am&lt;/h3>
&lt;p>By Day 22 mid-morning the architecture stack from Days 19-21
was firing together in one project for the first time. The
brief &lt;em>&amp;ldquo;Build a modern SaaS dashboard: nav row / 3 columns
with data / chart or graph / table&amp;rdquo;&lt;/em> produced:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Navbar substituted&lt;/strong> from the snippet library — logo
&lt;ul>
&lt;li>4 menu items + Sign-in CTA in a horizontal flex layout,
proper Material spacing&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>3 KPI cards in a horizontal row&lt;/strong> — &lt;code>.app__row--top&lt;/code>
flex utility from &lt;code>_base.css&lt;/code> working; cards substituted
from &lt;code>display/kpi-card-basic&lt;/code> with bracketed slots for
label/value/delta&lt;/li>
&lt;li>&lt;strong>Chart placeholder as a bracketed slot&lt;/strong> —
&lt;code>[chart placeholder — bar / line / pie, operator-specified]&lt;/code>,
the exact phrasing from &lt;code>@visionary&lt;/code>&amp;rsquo;s &lt;code>## Required features&lt;/code> section preserved all the way through to the
rendered output. NOT a comment placeholder — a content
placeholder the operator fills in later.&lt;/li>
&lt;li>&lt;strong>Full &lt;code>&amp;lt;table&amp;gt;&lt;/code> with 5 rows of bracketed mock data&lt;/strong> —
&lt;code>[Customer name]&lt;/code> / &lt;code>[Transaction amount]&lt;/code> / &lt;code>[Date]&lt;/code>
styled via the &lt;code>_base.css&lt;/code> raw-element table baselines
(uppercase headers, surface-container background, row
borders, hover state)&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Every piece of the week&amp;rsquo;s architecture firing together.&lt;/strong>
Snippet substitution + modular CSS + layout utilities + raw-
element baselines + persona-driven inline-content discipline.&lt;/p></description></item><item><title>Day 21 — 'stop dumping into the persona; build the library.'</title><link>/log/day-21/</link><pubDate>Wed, 20 May 2026 22:30:00 -0700</pubDate><guid>/log/day-21/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;stop dumping into the persona; build the library.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;h3 id="the-arc-of-day-21">The arc of Day 21&lt;/h3>
&lt;p>Day 20 proved that &lt;strong>chain orchestration belongs in code, not in the
model&amp;rsquo;s tool-call loop.&lt;/strong> Day 21 carries the lesson one layer
deeper: &lt;strong>complex-component generation belongs in a hand-crafted
library, not in the model&amp;rsquo;s per-pass output.&lt;/strong> Two days, two
moves from &amp;ldquo;ask the model harder&amp;rdquo; to &amp;ldquo;build the infrastructure
that obviates the ask.&amp;rdquo;&lt;/p>
&lt;p>Three concrete shifts shipped:&lt;/p></description></item><item><title>Day 20 — 'the chain moved into code, and the model went PFM.'</title><link>/log/day-20/</link><pubDate>Tue, 19 May 2026 22:00:00 -0700</pubDate><guid>/log/day-20/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the chain moved into code, and the model went PFM.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;h3 id="where-day-19-left-off">Where Day 19 left off&lt;/h3>
&lt;p>Day 19 closed with: structural fixes (AO.1 Part 3.1 project-scoped
read_file, frontmatter strip, max_iterations bump, persona
rewrites for @front-end and @css-wizard). Chain completing
end-to-end on the design studio&amp;rsquo;s &lt;code>@studio → @visionary → @front-end → @css-wizard&lt;/code> four-step pipeline. Quality landed but
features got dropped under cognitive load.&lt;/p>
&lt;p>Day 20&amp;rsquo;s opening hypothesis: persona discipline + a stronger
orchestrator model could close the feature-drop gap.&lt;/p></description></item><item><title>Day 19 — 'thesis on disk, studio on its feet.'</title><link>/log/day-19/</link><pubDate>Mon, 18 May 2026 22:00:00 -0700</pubDate><guid>/log/day-19/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;thesis on disk, studio on its feet.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;h3 id="two-halves-of-one-day">Two halves of one day&lt;/h3>
&lt;p>Day 18 was the surface-tightening pass. Day 19 split into two
unrelated halves that compose better than they look:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Morning: strategy moved from head to disk.&lt;/strong> THESIS.md +
two queued sprint docs (ARENA.1, OAI.1) captured the AI-game-
company arc that had been forming for weeks in conversation.&lt;/li>
&lt;li>&lt;strong>Evening: the design studio actually shipped.&lt;/strong> The chain
that&amp;rsquo;s been working since SD.2 was producing flat checkbox
bones; tonight it produced modern card UI with working
JavaScript on first emit.&lt;/li>
&lt;/ul>
&lt;p>The first half makes the case for why werbos exists in 2026&amp;rsquo;s
hosted-AI landscape. The second half makes one of werbos&amp;rsquo;s
flagship features finally usable. Strategy and shipping landed
on the same day.&lt;/p></description></item><item><title>Day 18 — 'the surface tightens — kanban, opt-in, MCP, update flow.'</title><link>/log/day-18/</link><pubDate>Sun, 17 May 2026 22:00:00 -0700</pubDate><guid>/log/day-18/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the surface tightens — kanban, opt-in, MCP, update flow.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;h3 id="distribution-work-doesnt-look-like-building">Distribution work doesn&amp;rsquo;t look like building&lt;/h3>
&lt;p>Day 17 was a build day: orchestration, security cycle, pipeline
UI. Day 18 wasn&amp;rsquo;t another build day — it was a &lt;em>tightening&lt;/em>
day. Gating power features behind opt-in flags. Defaulting to
clean surfaces. Surfacing the operator-facing strings that were
leaking the operator&amp;rsquo;s machine layout. Naming things on registries
before squatters do.&lt;/p>
&lt;p>None of it added new capability. All of it reduced friction for
the next operator who isn&amp;rsquo;t me.&lt;/p></description></item><item><title>Day 17 — 'five gates closed. one hour in, the orchestrator orchestrated.'</title><link>/log/day-17/</link><pubDate>Sun, 17 May 2026 01:00:00 -0700</pubDate><guid>/log/day-17/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;five gates closed. one hour in, the orchestrator orchestrated.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;h3 id="should-have-been-asleep">Should have been asleep&lt;/h3>
&lt;p>Wasn&amp;rsquo;t. AO.0 itself was patched at end of Day 16 (&lt;code>8ec97c3&lt;/code>) — the
one-line &lt;code>inline_tool_docs&lt;/code> propagation in &lt;code>_context_builder_for_agent&lt;/code>
— and the chain ran clean when I drove it programmatically via
&lt;code>/tmp/drive_*.py&lt;/code> scripts. But the chat-UI path still didn&amp;rsquo;t work
end-to-end. Four more gates stood between &amp;ldquo;model can tool-call&amp;rdquo;
and &amp;ldquo;operator types &lt;code>go&lt;/code> and gets a working artifact.&amp;rdquo;&lt;/p></description></item><item><title>Day 16 — 'the studio shipped. then the studio couldn't talk to itself. one line later, it could.'</title><link>/log/day-16/</link><pubDate>Sat, 16 May 2026 09:00:00 -0700</pubDate><guid>/log/day-16/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the studio shipped. then the studio couldn&amp;rsquo;t talk to itself. one line later, it could.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;h3 id="morning--preflight--safety-flips">Morning — preflight + safety flips&lt;/h3>
&lt;p>Locked the R.1 preflight decisions (&lt;code>af6f9fe&lt;/code>) and shipped R.2
T.3 (&lt;code>7c3477f&lt;/code>): &lt;code>werbos serve&lt;/code> now defaults to &lt;strong>operator-
approval&lt;/strong> before any listener binds an externally-reachable
port. The legacy &lt;code>--confirm-bind&lt;/code> opt-in is gone; you opt OUT
now with &lt;code>--unsafe-immediate-bind&lt;/code>. The same flip the security
audit wanted, just expressed the right way around — the safer
path is the path with fewer flags.&lt;/p></description></item><item><title>Day 15 — 'one reply, not six. then zero deferred. then the loop closed. then the little model learned.'</title><link>/log/day-15/</link><pubDate>Fri, 15 May 2026 11:30:00 -0700</pubDate><guid>/log/day-15/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;one reply, not six.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;h3 id="the-cascade">The cascade&lt;/h3>
&lt;p>Pairing worked. First real conversation in Slack — &lt;code>hello&lt;/code> →
six replies in 60 seconds, each iterating on the last:&lt;/p>
&lt;pre tabindex="0">&lt;code>werbos Hey back at you! What&amp;#39;s up?
werbos Another hello! I&amp;#39;m here to help, what&amp;#39;s on your mind?
werbos It looks like that&amp;#39;s just a greeting. How can I assist you today?
werbos Still looking for a conversation starter!
werbos I think we&amp;#39;ve had enough greetings for now. Seriously though, what&amp;#39;s on your mind?
werbos Let&amp;#39;s try a different approach. Can you tell me what&amp;#39;s been going on...
&lt;/code>&lt;/pre>&lt;p>The model was processing the same inbound 4-6 times, each time
adding its own previous reply to context and generating a fresh
&amp;ldquo;the user hasn&amp;rsquo;t responded yet, let me try again&amp;rdquo; message.
&lt;strong>1 inbound × 4 deliveries × 1.5 hellos sent ≈ 6.&lt;/strong> Math matched
the pattern exactly: Slack retries once at 3s, once at 6s, once
at 13s if the webhook doesn&amp;rsquo;t 200 quickly enough.&lt;/p></description></item><item><title>Day 14 — 'half a handshake.'</title><link>/log/day-14/</link><pubDate>Thu, 14 May 2026 23:00:00 -0700</pubDate><guid>/log/day-14/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;half a handshake.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>The bug yesterday&amp;rsquo;s Slack work shipped on top of: the pairing
handshake was half-built. Slack would tell the operator to &lt;code>run /social code in werbos chat&lt;/code>, but typing that into &lt;code>werbos chat&lt;/code>
got back &lt;em>&amp;ldquo;unknown command: /social&amp;rdquo;&lt;/em> — it dropped through to
buddy&amp;rsquo;s catch-all. The store had &lt;code>mint_pairing_code()&lt;/code> /
&lt;code>redeem_pairing_code()&lt;/code>, the Slack adapter knew &lt;code>/pair &amp;lt;CODE&amp;gt;&lt;/code>,
but nothing in between minted a code the operator could send.&lt;/p></description></item><item><title>Day 13 — 'the cross-repo trap.'</title><link>/log/day-13/</link><pubDate>Wed, 13 May 2026 23:55:00 -0700</pubDate><guid>/log/day-13/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the cross-repo trap.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Late-night fire drill that turned into a deploy-hygiene fix.&lt;/p>
&lt;h3 id="the-symptom">The symptom&lt;/h3>
&lt;p>&lt;code>POST /api/chats&lt;/code> returning 500 immediately after a SR8 redeploy.
Stack trace pointed straight at &lt;code>Agent.__init__()&lt;/code> rejecting a kwarg
&lt;code>one_call_per_iteration&lt;/code> that werbos was passing on every session
construction.&lt;/p>
&lt;p>The trap underneath: &lt;code>werbos/session/chat.py&lt;/code> had been bumped to
pass that kwarg, but &lt;code>pyproject.toml&lt;/code> was still pinned at an older
pitts SHA (&lt;code>107adb2&lt;/code>) that didn&amp;rsquo;t accept it. The local editable
checkout of pitts had the matching code, but uncommitted — so
local tests passed, the live SR8 build broke. Cross-repo half-
finished change.&lt;/p></description></item><item><title>Day 12 — 'play day.'</title><link>/log/day-12/</link><pubDate>Tue, 12 May 2026 23:45:00 -0700</pubDate><guid>/log/day-12/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;play day.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>V1.9 closed last night with the v1 baseline contract satisfied: 10
of 10 release-blocker sprints shipped, every dashboard surface
finally honest. Day 12 doesn&amp;rsquo;t extend the product surface; it
&lt;strong>plays&lt;/strong> on top of it. The morning fixes a bug the v1 baseline
left behind (chats with zero turns piling up as &amp;ldquo;(empty chat)&amp;rdquo;
rows in the sidebar). The evening builds a games suite. The night
ports a 2024 multiplayer game into the chat-ui as the first co-op
shape in the lineup — and the operator&amp;rsquo;s own art from two years
ago drops in cleanly because the slug naming was already right.&lt;/p></description></item><item><title>Day 11 — 'the dashboard stops lying.'</title><link>/log/day-11/</link><pubDate>Mon, 11 May 2026 22:30:00 -0700</pubDate><guid>/log/day-11/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the dashboard stops lying.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Day 10 shipped the dashboard as a shell — 9 routes, beautifully
rendered, mostly localStorage underneath. Day 11 made every row of
the per-element audit in &lt;code>gap-hunting.md&lt;/code> &lt;em>true&lt;/em>. The morning
locked the v1 baseline (Phase 14 in the roadmap; 10 sprints across
~25 days planned). The evening compressed all 10 into one session.
By 21:46 PT, every v1-scope surface — agents, perms, channels,
scheduler, integrations, models, settings, Home&amp;rsquo;s Recent activity
— answered to the server instead of to &lt;code>localStorage&lt;/code>.&lt;/p></description></item><item><title>Day 10 — 'fortify, then build.'</title><link>/log/day-10/</link><pubDate>Sun, 10 May 2026 21:00:00 -0700</pubDate><guid>/log/day-10/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;fortify, then build.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Day 9 closed the late-night Sprint Soc.1 thread; Day 10 splits cleanly
into two acts. The morning bolts the doors — two consecutive Black
Team / Red Team rounds that close 40 of 41 findings across every
surface. The evening, with the surface secured, builds the operator
dashboard from scratch: 9 sidebar routes, decoupled SPA, Starlette
static-mount, SR8 nginx wiring, all live on the tailnet by 9pm.&lt;/p></description></item><item><title>Day 9 — 'werbos goes outbound.'</title><link>/log/day-9/</link><pubDate>Sat, 09 May 2026 22:30:00 -0700</pubDate><guid>/log/day-9/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the adapter is the wire-format layer; the chat behavior doesn&amp;rsquo;t know which platform it&amp;rsquo;s talking through.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Day 8 broadened the surface area in four directions; Day 9 picks
&lt;em>one&lt;/em> direction and goes deep. werbos can already chat over CLI,
REPL, the React SPA, and &lt;code>werbos serve&lt;/code>&amp;rsquo;s HTTP/MCP surface. Sprint
Soc.1 (Phase 12 — external integrations) extends that reachability
to where people actually are: &lt;strong>Telegram, Slack, WhatsApp via
Twilio&lt;/strong> — three of four platforms shipped today, with the fourth
(Twitter/X) gated on a paid API tier and queued for next session.&lt;/p></description></item><item><title>Day 8 — 'Trust the roadmap, not the memo.'</title><link>/log/day-8/</link><pubDate>Sat, 09 May 2026 19:30:00 -0700</pubDate><guid>/log/day-8/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;trust the roadmap, not the memo.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Day 7&amp;rsquo;s lesson was &lt;em>the persona is the artifact&lt;/em> — F.2 dialed the
voice and K.0 stamped the floor of the memory ladder. Day 8 broadens
the surface area in four directions and runs into the day&amp;rsquo;s actual
discovery in the process: at this work pace, memory between sessions
ages out faster than I can refresh it. Two memories that read
&amp;ldquo;in progress&amp;rdquo; turned out to be already-closed, and one of them
nearly cost a duplicated implementation.&lt;/p></description></item><item><title>Day 6 — 'The infrastructure is the artifact.'</title><link>/log/day-6/</link><pubDate>Thu, 07 May 2026 20:00:00 -0700</pubDate><guid>/log/day-6/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;i like winning&amp;hellip; but i like better training data.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>That sentence — said mid-session, watching v1-c4 lose its third
straight game to the heuristic baseline — captures the day&amp;rsquo;s
load-bearing lesson. The bench eventually came back at &lt;strong>3% as O
versus the heuristic, with 0 forfeits across 100 games.&lt;/strong> The
&lt;em>format&lt;/em> trained perfectly: every reply was parseable JSON with
a legal column. The &lt;em>strategy&lt;/em> did not. v1-c4 played at
random-policy level.&lt;/p></description></item><item><title>Day 7 — 'The slider and the floor.'</title><link>/log/day-7/</link><pubDate>Fri, 08 May 2026 00:00:00 +0000</pubDate><guid>/log/day-7/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;the persona is the artifact.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>Day 6&amp;rsquo;s lesson was &lt;em>the infrastructure is the artifact&lt;/em> — the
v1-c4 LoRA flopped at 3% as O, but the corpus generator + bench
harness + heuristic fallback + observe adapter + security
hardening were the real shipping. Day 7 turns that lesson on the
persona surface itself. Two sprints land on opposite ends of the
&amp;ldquo;who is werbos?&amp;rdquo; axis:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>F.2 — the slider.&lt;/strong> The mirror slider ROADMAP § 10.7 has been
pitched since the start of the persona phase. Today it shipped
end-to-end. The 13% character (werbos&amp;rsquo;s own taste, peeves,
hard-no&amp;rsquo;s) is always full strength. The 87% voice (mirror /
agreement-tilt / memory volume) is a dial — 0 to 100 in the
composer chip, &lt;code>werbos chat --mirror 50&lt;/code>, &lt;code>/mirror N&lt;/code> REPL slash,
&lt;code>?mirror=N&lt;/code> query param, per-chat localStorage persistence,
&lt;code>.pfm&lt;/code> archive round-trip, daily-default memory, per-turn
override (&lt;code>/mirror N &amp;lt;message&amp;gt;&lt;/code>), and slide-DOWN as a
sycophancy-penalty event for v6+ training. Closed with an
anti-sycophancy CI gate (&lt;code>werbos eval --suite disagreement_survival&lt;/code>).&lt;/p></description></item><item><title>Day 5 — 'I think that is a glass of beer.'</title><link>/log/day-5/</link><pubDate>Thu, 07 May 2026 08:00:00 -0700</pubDate><guid>/log/day-5/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;i think that is a glass of beer&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>That sentence — generated by &lt;code>llama3.1:8b&lt;/code> on SR8, after &lt;code>moondream&lt;/code>
described a phone-camera photo, with the description injected as a
&lt;code>SystemMessage&lt;/code> that the agent reasoned over — closed the multimodal
loop on local hardware. Photo on phone → vision module → text model
with vision context → streamed reply on phone. End-to-end, on
your hardware, with your weights, from a single photo of a beer in
a &amp;ldquo;burning barrel&amp;rdquo; glass.&lt;/p></description></item><item><title>Day 4 — Two halves: closing the demo loop, then naming the orchestration plane.</title><link>/log/day-4/</link><pubDate>Wed, 06 May 2026 00:00:00 +0000</pubDate><guid>/log/day-4/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;Smallest, most secure, timeless, protocol we can make.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>The design directive that shaped the second half of Day 4. By the
end of the night, the orchestration plane had a name (&lt;code>observe&lt;/code>),
a flagship consumer (&lt;code>watchtower&lt;/code>), two planned siblings (&lt;code>warden&lt;/code>,
&lt;code>beacon&lt;/code>), three new repos, two SPEC drafts, and an Archaeologist
review verdict of &lt;strong>DURABLE&lt;/strong>.&lt;/p>
&lt;p>The morning was much more practical: closing every blocker that
showed up during yesterday&amp;rsquo;s bad demo.&lt;/p></description></item><item><title>Day 3 — The full pipeline.</title><link>/log/day-3/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>/log/day-3/</guid><description>&lt;blockquote>
&lt;p>&lt;em>&amp;ldquo;i finally got the full pipeline working — data streaming from the
server to my computer and my phone. the server auto-updates and
pulls on reboot.&amp;rdquo;&lt;/em>&lt;/p>&lt;/blockquote>
&lt;p>That was the line that closed the day. Everything else — the
heatmap, the mobile shell, the voice button, the paperclip, the
overnight LoRA, the server in the corner of the office — lined
up behind it.&lt;/p>
&lt;h2 id="what-shipped">What shipped&lt;/h2>
&lt;p>Order is roughly chronological: morning stats / training pipeline,
afternoon mobile, evening server bootstrap, late-night streaming.&lt;/p></description></item><item><title>Day 2 — The right test, the right answer.</title><link>/log/day-2/</link><pubDate>Sun, 03 May 2026 00:00:00 +0000</pubDate><guid>/log/day-2/</guid><description>&lt;p>The morning after the overnight LoRA train. v2-coder existed in two
candidate forms (iter-1000, val 0.850 plateau; iter-2000, val 0.811
new low). We didn&amp;rsquo;t know which was actually better — and the TTT bench
from yesterday told us &lt;em>both were worse than stock&lt;/em>, which felt wrong.&lt;/p>
&lt;p>Today we built the right benches, ran them, and learned the lesson
that&amp;rsquo;s going to shape every future training run: &lt;strong>val loss alone is
a deceptive metric.&lt;/strong> Multi-axis benchmarking is the only honest
signal.&lt;/p></description></item><item><title>Day 1 — He's a system citizen.</title><link>/log/day-1/</link><pubDate>Sat, 02 May 2026 00:00:00 +0000</pubDate><guid>/log/day-1/</guid><description>&lt;p>The day werbos stopped being something that lives inside one repo and
became a process other things can talk to. Two LLMs can hold a real
conversation now, and we have a &lt;em>number&lt;/em> that tells us if he&amp;rsquo;s getting
smarter.&lt;/p>
&lt;h2 id="what-shipped">What shipped&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>MCP chat bridge&lt;/strong> — &lt;code>chat_with_werbos_tool(message, sessionId?)&lt;/code>
and &lt;code>close_werbos_chat_tool(sessionId)&lt;/code>. Stdlib &lt;code>urllib&lt;/code>, no new
deps. Pass the returned &lt;code>sessionId&lt;/code> to keep a multi-turn thread
going. Every turn lands in the chat archive. &lt;em>(&lt;code>38208a1&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>&lt;code>werbos.games.ttt_bridge&lt;/code>&lt;/strong> — first protocol on the bridge.
Claude plays X with optimal minimax; werbos plays O via a
JSON-envelope prompt. Driver adjudicates rules locally and
re-prompts werbos with feedback when he hallucinates an illegal
move. &lt;em>(included in &lt;code>38208a1&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>&lt;code>werbos.games.speedcode&lt;/code>&lt;/strong> — second protocol. Same coding
spec → both sides write Python → judge with pytest in
isolated tempdirs. Smoke test on &lt;code>valid_parentheses&lt;/code> (12 cases):
both &lt;strong>PASS 12/12&lt;/strong>. Werbos&amp;rsquo;s solve time on stock 8B: 11.10s.
&lt;em>(&lt;code>2e00bd4&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>&lt;code>werbos.games.ttt_bench&lt;/code>&lt;/strong> — third protocol. Adds a minimax
oracle that scores every werbos move. Output: a single number we
can watch go up across model versions. &lt;em>(&lt;code>ecb0ef6&lt;/code>)&lt;/em>&lt;/li>
&lt;/ul>
&lt;h2 id="numbers-worth-keeping">Numbers worth keeping&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Metric&lt;/th>
 &lt;th>Value&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Hot-dog debate rounds (vs Claude)&lt;/td>
 &lt;td>3 / archived&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>TTT live games (Claude minimax X vs werbos LLM O)&lt;/td>
 &lt;td>2–0 Claude&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Speedcode pass rate (parentheses, stock 8B)&lt;/td>
 &lt;td>12 / 12&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>TTT-bench baseline, stock llama3.1:8b&lt;/strong>&lt;/td>
 &lt;td>&lt;strong>66.7% optimal, mean regret 0.333&lt;/strong>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Per-game time (Ollama, M1 8GB)&lt;/td>
 &lt;td>~22s&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Bridge parse failures across all runs&lt;/td>
 &lt;td>0&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Bridge illegal-move retries&lt;/td>
 &lt;td>self-corrected, never corrupted state&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="surprise-of-the-day">Surprise of the day&lt;/h2>
&lt;p>Realized I could type &lt;code>werbos&lt;/code> from &lt;code>/&lt;/code>, from &lt;code>~&lt;/code>, from any directory,
and he just &lt;em>runs&lt;/em>. The binary&amp;rsquo;s on &lt;code>$PATH&lt;/code>, memory is at
&lt;code>~/werbos/memory&lt;/code>, archives at &lt;code>~/werbos/chats/&lt;/code>, Ollama runs as a
daemon. He&amp;rsquo;s not tied to the repo anymore. He&amp;rsquo;s a &lt;strong>system citizen&lt;/strong>.&lt;/p></description></item><item><title>Day 0 — It's real.</title><link>/log/day-0/</link><pubDate>Fri, 01 May 2026 00:00:00 +0000</pubDate><guid>/log/day-0/</guid><description>&lt;p>The day everything came alive. Started with &lt;code>brew install ollama&lt;/code>,
ended with a fine-tuned 3B that knows my favorite color is teal. In
between: fourteen subsystems, one full UI, the off-grid training loop,
and the moment I realized models are just numbers.&lt;/p>
&lt;h2 id="what-shipped-in-order">What shipped (in order)&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>&lt;code>werbos tictactoe&lt;/code>&lt;/strong> — v0 milestone. Werbos plays himself; the
agent loop works end-to-end.&lt;/li>
&lt;li>&lt;strong>&lt;code>werbos.session.chat&lt;/code>&lt;/strong> — conversational session orchestrator
(PFM archive on exit). &lt;em>(&lt;code>21ec2d7&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>&lt;code>werbos chat&lt;/code>&lt;/strong> — interactive REPL with &lt;code>you&amp;gt;&lt;/code> / &lt;code>werbos&amp;gt;&lt;/code>,
quit tokens, EOF + Ctrl-C handling. &lt;em>(&lt;code>9cf60cc&lt;/code>, &lt;code>6996dee&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>Calculator tool&lt;/strong> — first concrete &lt;code>pitts.Tool&lt;/code>, safe-eval
expression parser. &lt;em>(&lt;code>dd68d50&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>&lt;code>werbos.eval&lt;/code> + &lt;code>werbos eval&lt;/code>&lt;/strong> — mcculloch Suite hookup,
basic_chat / calculator_use against the live model. &lt;em>(&lt;code>645ab43&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>Memory hookup&lt;/strong> — &lt;code>~/werbos/memory/&lt;/code> loaded into the system
prompt every turn. &lt;em>(&lt;code>f9ce0b6&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>&lt;code>werbos serve&lt;/code>&lt;/strong> — Starlette HTTP backend.
&lt;em>(&lt;code>af3cd42&lt;/code>, &lt;code>15d263b&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>&lt;code>werbos/ui/&lt;/code>&lt;/strong> — React frontend, Vite proxy, end-to-end browser
chat. &lt;em>(&lt;code>f92146e&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>ChatGPT importer&lt;/strong> — 3,138 conversations from a Google Drive
export → PFM archives. &lt;em>(&lt;code>58c36eb&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>SFT exporter&lt;/strong> — PFM → JSONL with &lt;code>--label&lt;/code> filter.
&lt;em>(&lt;code>8daee40&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>&lt;code>werbos train lora&lt;/code>&lt;/strong> — mlx-lm LoRA pipeline. &lt;em>(&lt;code>97ae6ef&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>CORS middleware&lt;/strong> + &lt;strong>Dockerfile / docker-compose&lt;/strong> for the
SR9 deployment story. &lt;em>(&lt;code>55890d3&lt;/code>, &lt;code>71ff301&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>&lt;code>werbos.tools.code&lt;/code>&lt;/strong> + &lt;strong>&lt;code>werbos code&lt;/code> CLI&lt;/strong> — file + shell
tools, three leash modes (read-only / write / shell).
&lt;em>(&lt;code>552ce22&lt;/code>, &lt;code>5c49e79&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>&lt;code>werbos.labels&lt;/code>&lt;/strong> + &lt;strong>&lt;code>--label&lt;/code> filter on export&lt;/strong> + &lt;strong>post-run
label prompt&lt;/strong> + &lt;strong>&lt;code>werbos label&lt;/code> CLI&lt;/strong> — the full &lt;strong>dogfood
loop&lt;/strong>. &lt;em>(&lt;code>76edc64&lt;/code>, &lt;code>0c1d7f5&lt;/code>, &lt;code>df16391&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>&lt;code>/api/runs&lt;/code> + Rate UI&lt;/strong> — thumbs up/down GUI for past runs.
&lt;em>(&lt;code>d2ee237&lt;/code>, &lt;code>5430206&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>SCSS migration&lt;/strong> — 1231-line monolith → 11 partials.
&lt;em>(&lt;code>95a2a88&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>&lt;code>werbos.mcp&lt;/code> + &lt;code>werbos mcp serve&lt;/code>&lt;/strong> — read-only MCP server,
five tools. The deliberate exception to off-grid.
&lt;em>(&lt;code>562d41f&lt;/code>, &lt;code>e1cada4&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>Bare &lt;code>werbos&lt;/code>&lt;/strong> drops into chat REPL. &lt;em>(&lt;code>4a34f4b&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>WIP phone view + &lt;code>/phone-api&lt;/code> proxy.&lt;/strong> &lt;em>(&lt;code>8e03d93&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>Archive-leak fix&lt;/strong> — &lt;code>atexit&lt;/code> + SIGTERM/SIGHUP so a killed
terminal still writes the PFM. &lt;em>(&lt;code>4d7d892&lt;/code>)&lt;/em>&lt;/li>
&lt;/ul>
&lt;h3 id="day-05-next-morning-am">Day 0.5 (next morning, AM)&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>&lt;code>werbos.backends.mlx_local&lt;/code>&lt;/strong> — &lt;code>pitts.Backend&lt;/code> backed by
mlx-lm. &lt;em>(&lt;code>a3d53af&lt;/code>)&lt;/em>&lt;/li>
&lt;li>&lt;strong>&lt;code>--backend mlx --adapter&lt;/code>&lt;/strong> wired into chat / code / eval / serve.
&lt;em>(&lt;code>3334b8c&lt;/code>)&lt;/em>&lt;/li>
&lt;/ul>
&lt;h2 id="numbers-worth-keeping">Numbers worth keeping&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Metric&lt;/th>
 &lt;th>Value&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Conversations imported (ChatGPT export)&lt;/td>
 &lt;td>3,138&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Adapter v1 base&lt;/td>
 &lt;td>Llama-3.2-3B-Instruct-4bit&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Adapter v1 size&lt;/td>
 &lt;td>~30 MB&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Adapter v1 best val loss&lt;/td>
 &lt;td>1.636 (down from 1.986, &lt;strong>-17.6%&lt;/strong>)&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Adapter v1 best iter&lt;/td>
 &lt;td>1250&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>First memory recalled by trained brain&lt;/td>
 &lt;td>&amp;ldquo;Jason&amp;rsquo;s favorite color is teal&amp;rdquo;&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>MCP read-only tools shipped&lt;/td>
 &lt;td>5&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Off-grid status of the inference loop&lt;/td>
 &lt;td>100%&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="ahas">AHAs&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>&amp;ldquo;Models are just numbers.&amp;rdquo;&lt;/strong> Trained weights are slot values in a
matrix. Training is &lt;em>nudging&lt;/em> those numbers, not adding new ones.&lt;/li>
&lt;li>&lt;strong>Adapter stacking is &amp;ldquo;I know kung fu.&amp;rdquo;&lt;/strong> Base model + frozen Δ₁ + Δ₂
at inference time. Like Neo: the brain doesn&amp;rsquo;t grow, the cable
uploads a new skill.&lt;/li>
&lt;li>&lt;strong>Merging averages, doesn&amp;rsquo;t add.&lt;/strong> Merge two 10B models → still
10B. To grow capacity, &lt;strong>concatenation&lt;/strong> (add new layers), not merge.&lt;/li>
&lt;li>&lt;strong>Four primitives:&lt;/strong> training (fills slots), merging (averages
values), concatenation (adds slots), distillation (compresses
big → small).&lt;/li>
&lt;li>&lt;strong>Off-grid economics:&lt;/strong> cloud LLM agent at 24h = ~$50/day; local
laptop at full tilt = ~$0.03/day in electricity. &lt;strong>Three orders of
magnitude.&lt;/strong> The whole reason werbos exists.&lt;/li>
&lt;/ul>
&lt;h2 id="surprise-of-the-day">Surprise of the day&lt;/h2>
&lt;p>Llama-3.1-8B OOM&amp;rsquo;d at the first gradient step on M1 8GB. Hardware
ceiling is real. Dropped to 3B-class for training; kept 8B for
inference. The fleet roles got crisp: M1 = dev + train (3B max),
SR8 = inference (13B+), Pi 5 = always-on orchestrator.&lt;/p></description></item><item><title>About</title><link>/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/about/</guid><description>&lt;p>Renting intelligence by the token was never the endgame. werbos is a foundry:
a place to mint a model that&amp;rsquo;s yours, ground it in your own library, and run it
on your own box — off-grid, sub-second, and honest about what it doesn&amp;rsquo;t know.&lt;/p>
&lt;p>We build in the open. The developer journal has run 159 days and counting —
benchmarks, dead ends, and all. If you want to see how the machine gets made,
it&amp;rsquo;s all written down.&lt;/p></description></item><item><title>Compose Your Model</title><link>/compose/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/compose/</guid><description/></item><item><title>Features</title><link>/features/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/features/</guid><description/></item><item><title>How does werbos work?</title><link>/how-does-it-work/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/how-does-it-work/</guid><description>&lt;p>Most AI is one giant model in someone else&amp;rsquo;s data center. werbos is the
opposite bet: a &lt;strong>small model you own&lt;/strong>, pointed at a &lt;strong>library you
curate&lt;/strong>, with a &lt;strong>verifier&lt;/strong> that refuses to guess. The clever part
isn&amp;rsquo;t the weights — it&amp;rsquo;s the engine around them.&lt;/p>
&lt;p>One line carries the whole design:&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>capability = model × library&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>The model is the &lt;em>cursor&lt;/em> — the thing that reads, picks, and phrases.
The library is the &lt;em>knowledge&lt;/em> — everything the model is allowed to
know. You grow capability by growing the &lt;strong>library&lt;/strong>, not by renting a
bigger model. That&amp;rsquo;s why it stays cheap, stays local, and stays yours.&lt;/p></description></item><item><title>Knowledge Graph</title><link>/graph/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/graph/</guid><description/></item><item><title>Levels of Progression</title><link>/lop/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/lop/</guid><description>&lt;h3 id="the-lines-that-dont-move">The lines that don&amp;rsquo;t move&lt;/h3>
&lt;p>Across every level, five things never change — they’re the constitution, not the roadmap:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Owned weights.&lt;/strong> No open-model substitution, ever. The goal is &lt;em>our&lt;/em> model.&lt;/li>
&lt;li>&lt;strong>Library is truth.&lt;/strong> Cards are retrieved and cited — they never become weights. Knowledge in weights is confident hallucination with no honest abstain; that’s the one failure this whole thing exists to prevent.&lt;/li>
&lt;li>&lt;strong>Honest-abstain&lt;/strong> — and, going forward, &lt;strong>honest-synthesis&lt;/strong>: never assert, always demonstrate. A running, verified thing, or an honest “I don’t know.”&lt;/li>
&lt;li>&lt;strong>Local-first.&lt;/strong> Your data stays on your box.&lt;/li>
&lt;li>&lt;strong>Every gate is a number.&lt;/strong> “We hit 3.0” is a measurement on the sealed gauntlet, never a vibe.&lt;/li>
&lt;/ul>
&lt;p>Those five aren’t just principles — they’re the &lt;strong>werbosOS kernel&lt;/strong>: the contract every level inherits and no app can break. Read the ladder that way and it stops being a product roadmap. It’s &lt;strong>werbosOS coming online&lt;/strong>, one earned level at a time — hardware, then a kernel, then organs (senses, tongue, reasoning), then apps (the chat, the dating lane, the games, Smallville), until at &lt;strong>5.5&lt;/strong> it wakes up as an ambient companion that sees you, knows you, and won’t lie to you. An operating system you &lt;em>own&lt;/em>, that knows only what you tell it.&lt;/p></description></item><item><title>Live Demo</title><link>/demo/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/demo/</guid><description/></item><item><title>Terms</title><link>/terms/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/terms/</guid><description>&lt;p>This page is a placeholder. werbos is a personal project; for now,
treat the content here as MIT-licensed prose with no warranty. The
source code is MIT.&lt;/p>
&lt;p>When this page lands properly, it will cover:&lt;/p>
&lt;ul>
&lt;li>Privacy: this site sets no cookies, runs no trackers, and does not
log anything beyond Netlify&amp;rsquo;s standard request logs.&lt;/li>
&lt;li>Content license: log + map + docs prose under [CC BY 4.0]
(&lt;a href="https://creativecommons.org/licenses/by/4.0/)">https://creativecommons.org/licenses/by/4.0/)&lt;/a>.&lt;/li>
&lt;li>Code license: &lt;a href="https://github.com/jasonsutter87/werbos/blob/main/LICENSE">MIT&lt;/a>.&lt;/li>
&lt;li>No warranty: werbos is research-grade software. Don&amp;rsquo;t use it for
anything mission-critical without your own validation.&lt;/li>
&lt;/ul>
&lt;p>For now: assume the above. Read &lt;a href="/log/">the log&lt;/a> for what werbos
actually does, on whose hardware, with what data.&lt;/p></description></item><item><title>The Flow</title><link>/flow/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/flow/</guid><description>&lt;p>The &lt;a href="/map/">map&lt;/a> is the conceptual field guide — what an LLM IS,
what training does, how adapters stack. &lt;strong>This page is the system
flow&lt;/strong> — every component an operator turn passes through, the
artifacts each component writes, and how an operator debugs when
the answer is wrong.&lt;/p>
&lt;a class="flow-cta" href="/flow-explorer.html">
 &lt;span class="flow-cta__icon" aria-hidden="true">🌐&lt;/span>
 &lt;span class="flow-cta__body">
 &lt;span class="flow-cta__title">Explore the whole flow interactively&amp;nbsp;→&lt;/span>
 &lt;span class="flow-cta__sub">All 169 components as one navigable graph — drag, zoom, search, and click any node to walk its connections across every layer.&lt;/span>
 &lt;/span>
&lt;/a>
&lt;p class="flow-cta__alt">Want to reason about the whole system with an LLM? Grab the &lt;a href="/flow-graph.txt">plain-text graph export&amp;nbsp;↓&lt;/a> — paste it into Claude or ChatGPT.&lt;/p></description></item><item><title>The Map</title><link>/map/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/map/</guid><description>&lt;p>The map answers the &lt;em>what is&lt;/em> questions: training, adapters, hardware,
the four operations, the off-grid economic argument. It&amp;rsquo;s the
companion to the &lt;a href="/log/">log&lt;/a>, which answers &lt;em>what just changed&lt;/em>.&lt;/p>
&lt;h2 id="big-picture-one-diagram">Big picture (one diagram)&lt;/h2>
&lt;pre tabindex="0">&lt;code>+--------------------------------------------------------------+
| BASE MODEL |
| (e.g. Llama-3.2-3B-Instruct, weights frozen) |
+--------------------------------------------------------------+
 | inference time
 v
+--------------------------------------------------------------+
| +ADAPTER 1 (~30 MB LoRA delta, your data, your style) |
| +ADAPTER 2 (optional, stack as many as you like) |
+--------------------------------------------------------------+
 |
 v
+--------------------------------------------------------------+
| YOUR HARDWARE: M1 (dev/train, 3B max), |
| SR8 Ryzen (inference, 13B+), Pi 5 (always-on orchestrator) |
+--------------------------------------------------------------+
&lt;/code>&lt;/pre>&lt;p>If you only memorize one diagram, that&amp;rsquo;s it. The brain is the base.
The skills are the adapters. You stack them at inference. Like Neo
plugging in &lt;em>&amp;ldquo;I know kung fu.&amp;rdquo;&lt;/em>&lt;/p></description></item><item><title>The Mind</title><link>/mind/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/mind/</guid><description>&lt;p>The &lt;a href="/map/">map&lt;/a> is the field guide to what werbos &lt;em>is&lt;/em>; the &lt;a href="/flow/">flow&lt;/a> is how
a turn moves through it. &lt;strong>This page is werbos&amp;rsquo;s &lt;em>mind&lt;/em>&lt;/strong> — the dimensions it&amp;rsquo;s
measured on, what each one means, and the ones it can&amp;rsquo;t measure yet.&lt;/p>
&lt;p>The psychology angle is the one axis a frontier model can&amp;rsquo;t compete on. Measuring
and improving a mind needs a model that&amp;rsquo;s &lt;strong>small, local, legible, editable, and
prunable&lt;/strong> — exactly werbos&amp;rsquo;s properties and exactly what a 200B black box isn&amp;rsquo;t.
The forest is the instrument; the mind is what it&amp;rsquo;s &lt;em>for&lt;/em>.&lt;/p></description></item><item><title>The Stack — what's hooked up, who's doing the work</title><link>/stack/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/stack/</guid><description>&lt;p>A running tally of &lt;em>who is actually doing the work&lt;/em> across werbos — because the
common question (&amp;ldquo;is this Claude? ollama? something we built?&amp;rdquo;) has a foggy answer
until you separate the axes that keep getting conflated.&lt;/p>
&lt;p>&lt;em>Snapshot: Day 46 — 2026-06-16. This drifts; treat it as a dated inventory, not a
spec.&lt;/em>&lt;/p>
&lt;h2 id="first-untangle-the-categories">First, untangle the categories&lt;/h2>
&lt;p>The usual five labels — &lt;em>hooked up · open weights · hand-rolled · Claude · ollama&lt;/em> —
aren&amp;rsquo;t parallel. Two of them collapse and one splits:&lt;/p></description></item><item><title>Who it's for</title><link>/who/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/who/</guid><description/></item></channel></rss>