Add full WhetstoneRSA cost story deck

This commit is contained in:
2026-04-30 19:01:42 +00:00
parent 39e060349e
commit 750353aba6
2 changed files with 1660 additions and 0 deletions

View File

@@ -0,0 +1,935 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WhetstoneRSA - When LLMs Are Overkill</title>
<style>
:root {
--bg: #0f1117;
--panel: #161b27;
--text: #e2e8f0;
--muted: #94a3b8;
--dim: #64748b;
--line: #2d3748;
--blue: #60a5fa;
--cyan: #22d3ee;
--green: #4ade80;
--amber: #fbbf24;
--red: #fb7185;
}
* { box-sizing: border-box; }
html, body {
margin: 0;
min-height: 100%;
background: var(--bg);
color: var(--text);
font-family: "Segoe UI", system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
}
body { overflow: hidden; }
.deck { width: 100vw; height: 100vh; position: relative; }
.slide {
position: absolute;
inset: 0;
display: none;
padding: 5.5vh 7vw;
overflow: hidden;
}
.slide.active {
display: grid;
grid-template-rows: auto 1fr auto;
gap: 28px;
}
.kicker {
color: var(--dim);
font-size: 0.78rem;
letter-spacing: 0.16em;
text-transform: uppercase;
font-weight: 700;
}
h1, h2 {
margin: 0;
letter-spacing: 0;
font-weight: 680;
}
h1 {
font-size: clamp(3rem, 7vw, 6.6rem);
line-height: 0.98;
max-width: 1080px;
}
h2 {
font-size: clamp(2.35rem, 5.4vw, 5.15rem);
line-height: 1.02;
max-width: 1080px;
}
.subtitle {
color: var(--muted);
font-size: clamp(1.2rem, 2.2vw, 2rem);
line-height: 1.35;
max-width: 980px;
}
.body {
display: flex;
flex-direction: column;
justify-content: center;
min-height: 0;
}
.center { align-items: center; text-align: center; }
.center h1, .center h2, .center .subtitle { margin-left: auto; margin-right: auto; }
.bigline {
font-size: clamp(2rem, 4.1vw, 4.35rem);
line-height: 1.08;
font-weight: 650;
}
.stack { display: flex; flex-direction: column; gap: 18px; max-width: 1080px; }
.bullets {
margin: 0;
padding: 0;
list-style: none;
display: grid;
gap: 18px;
max-width: 980px;
}
.bullets li {
position: relative;
padding-left: 34px;
color: var(--text);
font-size: clamp(1.55rem, 2.8vw, 3rem);
line-height: 1.13;
font-weight: 560;
}
.bullets li::before {
content: "";
position: absolute;
left: 0;
top: 0.46em;
width: 12px;
height: 12px;
border-radius: 999px;
background: var(--cyan);
}
.small-bullets li { font-size: clamp(1.22rem, 2vw, 2.1rem); }
code {
color: var(--cyan);
background: rgba(34, 211, 238, 0.08);
border: 1px solid rgba(34, 211, 238, 0.16);
border-radius: 6px;
padding: 0.08em 0.28em;
font-family: "SFMono-Regular", Consolas, "Liberation Mono", monospace;
font-size: 0.9em;
}
pre {
margin: 0;
background: #111827;
border: 1px solid var(--line);
border-radius: 8px;
padding: 26px;
color: var(--text);
font-size: clamp(1.15rem, 1.85vw, 1.95rem);
line-height: 1.36;
overflow: hidden;
}
pre code {
background: none;
border: 0;
padding: 0;
color: var(--text);
font-size: 1em;
}
.flow {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 14px;
align-items: stretch;
width: min(1120px, 100%);
}
.flow.three { grid-template-columns: repeat(3, 1fr); }
.flow.two { grid-template-columns: repeat(2, 1fr); }
.box {
border: 1px solid var(--line);
background: var(--panel);
border-radius: 8px;
padding: 24px;
min-height: 140px;
display: flex;
flex-direction: column;
justify-content: center;
gap: 12px;
}
.box .label {
color: var(--dim);
font-size: 0.72rem;
letter-spacing: 0.12em;
text-transform: uppercase;
font-weight: 800;
}
.box .main {
font-size: clamp(1.25rem, 2.15vw, 2.25rem);
line-height: 1.1;
font-weight: 650;
}
.box.blue { border-color: rgba(96, 165, 250, 0.65); }
.box.cyan { border-color: rgba(34, 211, 238, 0.65); }
.box.green { border-color: rgba(74, 222, 128, 0.65); }
.box.amber { border-color: rgba(251, 191, 36, 0.65); }
.box.red { border-color: rgba(251, 113, 133, 0.65); }
.metric {
display: inline-flex;
align-items: baseline;
gap: 12px;
margin-right: 28px;
margin-bottom: 12px;
}
.metric strong {
font-size: clamp(2.8rem, 5.8vw, 5.8rem);
color: var(--cyan);
line-height: 1;
}
.metric span {
color: var(--muted);
font-size: clamp(1rem, 1.55vw, 1.45rem);
}
.table {
width: min(1120px, 100%);
border-collapse: collapse;
font-size: clamp(1rem, 1.55vw, 1.5rem);
}
.table th, .table td {
border-bottom: 1px solid var(--line);
padding: 18px 16px;
text-align: left;
vertical-align: top;
}
.table th {
color: var(--dim);
font-size: 0.75em;
letter-spacing: 0.12em;
text-transform: uppercase;
}
.table td { color: var(--text); }
.table .muted { color: var(--muted); }
.footer {
display: flex;
justify-content: space-between;
align-items: center;
color: var(--dim);
font-size: 0.88rem;
}
.progress {
position: fixed;
left: 0;
bottom: 0;
height: 4px;
background: var(--cyan);
width: 0;
transition: width 120ms ease-out;
z-index: 10;
}
.notes {
position: fixed;
right: 18px;
bottom: 22px;
width: min(560px, calc(100vw - 36px));
max-height: 38vh;
overflow: auto;
background: rgba(15, 17, 23, 0.96);
border: 1px solid var(--line);
border-radius: 8px;
padding: 16px 18px;
color: var(--muted);
font-size: 0.95rem;
line-height: 1.45;
display: none;
z-index: 20;
}
.notes.visible { display: block; }
.notes strong { color: var(--text); }
.hint {
position: fixed;
top: 16px;
right: 18px;
color: var(--dim);
font-size: 0.8rem;
z-index: 11;
}
.accent { color: var(--cyan); }
.green-text { color: var(--green); }
.amber-text { color: var(--amber); }
.red-text { color: var(--red); }
@media (max-width: 800px) {
.slide { padding: 5vh 6vw; }
.flow, .flow.three, .flow.two { grid-template-columns: 1fr; }
.box { min-height: 96px; }
.hint { display: none; }
}
@media print {
body { overflow: visible; }
.deck { height: auto; }
.slide, .slide.active {
position: relative;
display: grid;
page-break-after: always;
height: 100vh;
}
.hint, .progress, .notes { display: none !important; }
}
</style>
</head>
<body>
<div class="deck" id="deck">
<section class="slide active" data-notes="Open with the product experience, not the internals. The point is that AST-first generation already made software generation feel fast. RSA is the next optimization layer.">
<div class="kicker">WhetstoneRSA</div>
<div class="body center">
<h1>Product Spec In. Program Out.</h1>
<p class="subtitle">Then make the planning layer local, cheaper, and repeatable.</p>
</div>
<div class="footer"><span>1</span><span>main claim</span></div>
</section>
<section class="slide" data-notes="This is the practical hook. You saw agentic coding take about half an hour for a Twitter clone; your AST-first pipeline produced a comparable program in about five minutes.">
<div class="kicker">The thing that matters</div>
<div class="body center">
<h2>A working program in about five minutes.</h2>
<p class="subtitle">That is already a different software-building experience.</p>
</div>
<div class="footer"><span>2</span><span>speed is the hook</span></div>
</section>
<section class="slide" data-notes="Use this as a comparison, not a benchmark paper. The audience will understand the visceral difference between watching an agent work and seeing a program appear quickly.">
<div class="kicker">Comparison I watched</div>
<div class="body center">
<div>
<div class="metric"><strong>30</strong><span>minutes agent loop</span></div>
<div class="metric"><strong>5</strong><span>minutes AST-first pipeline</span></div>
</div>
<p class="subtitle">Same general class of app-building demo.</p>
</div>
<div class="footer"><span>3</span><span>rough observed scale</span></div>
</section>
<section class="slide" data-notes="Make this claim carefully: RSA did not cause the original speedup. AST-first code generation did. RSA is for removing remaining repeated model calls from that already-fast pipeline.">
<div class="kicker">Important distinction</div>
<div class="body center">
<h2>AST-first generation created the speedup.</h2>
<p class="subtitle">RSA attacks the remaining repeated LLM decisions.</p>
</div>
<div class="footer"><span>4</span><span>keep the claim clean</span></div>
</section>
<section class="slide" data-notes="This is the pipeline intuition from your earlier AST-first talk. The model is not typing a whole repo line by line like a chat agent.">
<div class="kicker">Why AST-first is fast</div>
<div class="body">
<ul class="bullets small-bullets">
<li>plan into structured work</li>
<li>generate from AST shape</li>
<li>validate against contracts</li>
<li>avoid long wandering agent loops</li>
</ul>
</div>
<div class="footer"><span>5</span><span>structure beats wandering</span></div>
</section>
<section class="slide" data-notes="This is the bridge to RSA. Even after AST-first generation, planning still has a lot of little choices that were bundled into LLM calls.">
<div class="kicker">The remaining model work</div>
<div class="body center">
<h2>The pipeline still has planning decisions.</h2>
<p class="subtitle">Task splits, target files, required tools, acceptance checks, prep gates.</p>
</div>
<div class="footer"><span>6</span><span>where RSA fits</span></div>
</section>
<section class="slide" data-notes="Now start the general argument: many of those planning choices do not need a full language model. They are small menus with messy inputs.">
<div class="kicker">The starting point</div>
<div class="body center">
<h2>LLMs are amazing.</h2>
<p class="subtitle">But many software decisions are smaller than an LLM.</p>
</div>
<div class="footer"><span>7</span><span>not anti-LLM</span></div>
</section>
<section class="slide" data-notes="This is the phrase to repeat. It is understandable without data-science vocabulary.">
<div class="kicker">The shape</div>
<div class="body center">
<div class="bigline">The input can be huge.</div>
<div class="bigline"><span class="accent">The output is small.</span></div>
</div>
<div class="footer"><span>3</span><span>the key distinction</span></div>
</section>
<section class="slide" data-notes="Use a generic example before WhetstoneDSL so nobody is lost in project-specific nouns.">
<div class="kicker">Example request</div>
<div class="body center">
<h2><code>show me the failed builds from yesterday</code></h2>
</div>
<div class="footer"><span>4</span><span>messy human phrasing</span></div>
</section>
<section class="slide" data-notes="The user phrasing is flexible. The application behavior is not infinite.">
<div class="kicker">Same intent, many phrasings</div>
<div class="body">
<ul class="bullets small-bullets">
<li>what broke in CI yesterday</li>
<li>pull up yesterday's red builds</li>
<li>did the pipeline fail last night</li>
<li>which build jobs failed since yesterday</li>
</ul>
</div>
<div class="footer"><span>5</span><span>input variety</span></div>
</section>
<section class="slide" data-notes="Now flip the framing. We do not need to generate an answer. We need to choose an allowed action.">
<div class="kicker">What the app actually needs</div>
<div class="body center">
<div class="flow three">
<div class="box cyan"><div class="label">action</div><div class="main">search_builds</div></div>
<div class="box blue"><div class="label">status</div><div class="main">failed</div></div>
<div class="box green"><div class="label">date</div><div class="main">yesterday</div></div>
</div>
</div>
<div class="footer"><span>6</span><span>small structured output</span></div>
</section>
<section class="slide" data-notes="This is the first scale point. The output menu can be counted.">
<div class="kicker">Output scale</div>
<div class="body center">
<pre><code>5 actions x 4 statuses x 4 date buckets
= about 80 structured outputs</code></pre>
</div>
<div class="footer"><span>7</span><span>small menu</span></div>
</section>
<section class="slide" data-notes="This is where regex looks good. It is cheap, fast, local, and totally controlled.">
<div class="kicker">Classical code starts well</div>
<div class="body center">
<pre><code>if text has "failed" and "build":
action = search_builds
if text has "yesterday":
date = yesterday</code></pre>
</div>
<div class="footer"><span>8</span><span>simple at first</span></div>
</section>
<section class="slide" data-notes="The cost is not runtime. The cost is authoring and maintaining all the variants.">
<div class="kicker">Then regex pays the human tax</div>
<div class="body center">
<h2>You enumerate the input side.</h2>
<p class="subtitle">Every new phrase becomes another pattern, exception, or bug.</p>
</div>
<div class="footer"><span>9</span><span>input enumeration</span></div>
</section>
<section class="slide" data-notes="Use conservative numbers. This is not a precise theorem. It is an engineering intuition pump.">
<div class="kicker">Rule explosion</div>
<div class="body center">
<pre><code>5 actions
x 10 common phrasings
x 4 statuses
x 8 time phrasings
= 1,600-ish rule cases</code></pre>
</div>
<div class="footer"><span>10</span><span>conservative example</span></div>
</section>
<section class="slide" data-notes="The classic system is reliable after it matches. The painful part is reaching that match across human language.">
<div class="kicker">Regex tradeoff</div>
<div class="body">
<ul class="bullets">
<li>excellent output control</li>
<li>tiny runtime cost</li>
<li>input coverage gets expensive</li>
</ul>
</div>
<div class="footer"><span>11</span><span>great gate, painful input</span></div>
</section>
<section class="slide" data-notes="This is why developers reach for LLMs. They collapse the input enumeration problem.">
<div class="kicker">LLMs feel easy</div>
<div class="body center">
<h2>They understand the messy input.</h2>
<p class="subtitle">One prompt can replace a pile of brittle phrase rules.</p>
</div>
<div class="footer"><span>12</span><span>the appeal is real</span></div>
</section>
<section class="slide" data-notes="But the machine you brought is not sized to the software decision. It is a general language engine.">
<div class="kicker">But the scale is wrong</div>
<div class="body center">
<h2>A giant general model</h2>
<p class="subtitle">choosing from a tiny application menu.</p>
</div>
<div class="footer"><span>13</span><span>overkill</span></div>
</section>
<section class="slide" data-notes="Use current OpenAI API prices as a familiar external scale. Mention these are API examples, not your local experiment.">
<div class="kicker">API runtime scale</div>
<div class="body center">
<table class="table">
<tr><th>Model</th><th>Input</th><th>Output</th></tr>
<tr><td>gpt-5.4-mini</td><td>$0.75 / 1M tokens</td><td>$4.50 / 1M tokens</td></tr>
<tr><td>gpt-5.4</td><td>$2.50 / 1M tokens</td><td>$15 / 1M tokens</td></tr>
<tr><td>gpt-5.5</td><td>$5 / 1M tokens</td><td>$30 / 1M tokens</td></tr>
</table>
</div>
<div class="footer"><span>14</span><span>OpenAI pricing, checked Apr 2026</span></div>
</section>
<section class="slide" data-notes="This puts the user's 125-program example set on the screen. The exact taskitem logs did not survive in the cloned WhetstoneDSL repo, but WhetstoneRSA has extracted rows from the taskitem runs.">
<div class="kicker">WhetstoneDSL example set</div>
<div class="body center">
<div>
<div class="metric"><strong>100</strong><span>easy programs</span></div>
<div class="metric"><strong>25</strong><span>challenging programs</span></div>
</div>
<p class="subtitle">125 product specs used as generation/evaluation examples.</p>
</div>
<div class="footer"><span>15</span><span>the benchmark scale</span></div>
</section>
<section class="slide" data-notes="These are measured from the extracted WhetstoneRSA corpus, not invented. This tells us how many planning artifacts survived: 999 runs, 1321 taskitems, four extracted gate rows each.">
<div class="kicker">Measured extraction slice</div>
<div class="body center">
<table class="table">
<tr><th>Artifact</th><th>Count</th></tr>
<tr><td>runs</td><td>999</td></tr>
<tr><td>taskitems</td><td>1,321</td></tr>
<tr><td>extracted gate rows</td><td>5,284</td></tr>
<tr><td>gates per taskitem</td><td>4 extracted</td></tr>
</table>
</div>
<div class="footer"><span>16</span><span>local extracted data</span></div>
</section>
<section class="slide" data-notes="This is the conversion to the 125-program set. Use conservative language: the extracted corpus averages 1.32 taskitems per run. The decision audit says generate_taskitems bundles 10+ decisions per taskitem.">
<div class="kicker">125 programs implies</div>
<div class="body center">
<pre><code>125 programs x 1.32 taskitems/program
= ~165 taskitems
~165 taskitems x 10+ planning decisions
= ~1,650+ decisions</code></pre>
</div>
<div class="footer"><span>17</span><span>planning decision count</span></div>
</section>
<section class="slide" data-notes="This is where the cost story becomes tangible. Even a fast AST-first pipeline still pays for general-model reasoning unless we move repeatable choices local.">
<div class="kicker">Planning-only token estimate</div>
<div class="body center">
<pre><code>125 specs:
~56K planning input tokens
~99K planning output tokens
This is before implementation calls.</code></pre>
</div>
<div class="footer"><span>18</span><span>planning layer only</span></div>
</section>
<section class="slide" data-notes="These costs look small for one demo batch. That is the point: the scary cost is not the demo. It is scaling the same approach to bigger programs, retries, regressions, and many users.">
<div class="kicker">125-program planning cost</div>
<div class="body center">
<table class="table">
<tr><th>Model</th><th>Planning-only estimate</th></tr>
<tr><td>gpt-5.4-mini</td><td>~$0.49</td></tr>
<tr><td>gpt-5.4</td><td>~$1.63</td></tr>
<tr><td>gpt-5.5</td><td>~$3.25</td></tr>
</table>
</div>
<div class="footer"><span>19</span><span>small demo, real meter</span></div>
</section>
<section class="slide" data-notes="Now make the cost real: implementation calls dominate. These are example task implementation sizes, not exact WhetstoneDSL logs.">
<div class="kicker">Add implementation calls</div>
<div class="body center">
<pre><code>165 taskitems
x 5K input + 2K output tokens
= ~826K input + ~330K output
Still a modest example.</code></pre>
</div>
<div class="footer"><span>20</span><span>implementation dominates</span></div>
</section>
<section class="slide" data-notes="Show both moderate and heavier implementation budgets. This helps people see why codebase scale matters more than toy app demos.">
<div class="kicker">Estimated API cost</div>
<div class="body center">
<table class="table">
<tr><th>Model</th><th>Moderate tasks</th><th>Heavier tasks</th></tr>
<tr><td>gpt-5.4-mini</td><td>~$2.60</td><td>~$6.70</td></tr>
<tr><td>gpt-5.4</td><td>~$8.65</td><td>~$22.30</td></tr>
<tr><td>gpt-5.5</td><td>~$17.30</td><td>~$44.60</td></tr>
</table>
</div>
<div class="footer"><span>21</span><span>one 125-program batch</span></div>
</section>
<section class="slide" data-notes="This connects to the real-world market: companies can spend huge amounts on model tokens to avoid headcount, but the meter repeats on every run and every retry. Keep this as an economic pressure statement, not a precise accusation.">
<div class="kicker">Scale changes the economics</div>
<div class="body center">
<h2>At codebase scale, token spend becomes infrastructure spend.</h2>
<p class="subtitle">Retries, larger context, regressions, and many users multiply the meter.</p>
</div>
<div class="footer"><span>22</span><span>the bill compounds</span></div>
</section>
<section class="slide" data-notes="This is an illustrative scaling example, not a claim about the WhetstoneDSL benchmark. It gives people a feel for how token budgets get into serious money.">
<div class="kicker">Team-scale intuition</div>
<div class="body center">
<pre><code>$20 per substantial generation run
x 10,000 runs/month
= $200,000/month
before engineer review time</code></pre>
</div>
<div class="footer"><span>23</span><span>illustrative scale</span></div>
</section>
<section class="slide" data-notes="This is the economic pitch. Not zero cost, but a different cost shape: own a few GPUs, pay subscriptions where useful, and move repeated planning local.">
<div class="kicker">Different cost shape</div>
<div class="body center">
<h2>From recurring token meter</h2>
<p class="subtitle">toward a few good GPUs, local gates, and occasional subscriptions.</p>
</div>
<div class="footer"><span>23</span><span>ownership vs meter</span></div>
</section>
<section class="slide" data-notes="This is where you pivot to the local model story. The original plan was reasonable: use a local SLM and LoRA.">
<div class="kicker">My original plan</div>
<div class="body center">
<h2>Use LoRA on a local SLM.</h2>
<p class="subtitle">Adapt a small language model to WhetstoneDSL decisions.</p>
</div>
<div class="footer"><span>16</span><span>the first instinct</span></div>
</section>
<section class="slide" data-notes="LoRA adapters can be small, but the base model still has to be loaded and run. That is the key point.">
<div class="kicker">LoRA still carries the base model</div>
<div class="body">
<ul class="bullets">
<li>1B / 3B / 7B parameter base</li>
<li>adapter is small</li>
<li>runtime model is still big</li>
</ul>
</div>
<div class="footer"><span>17</span><span>adapter small, base still large</span></div>
</section>
<section class="slide" data-notes="This is the conceptual turn. Do not adapt a big object until you prove the task deserves one.">
<div class="kicker">The better question</div>
<div class="body center">
<h2>Was the task ever large enough to deserve that model?</h2>
</div>
<div class="footer"><span>18</span><span>question the premise</span></div>
</section>
<section class="slide" data-notes="Now introduce WhetstoneDSL with audience context from your AST-first talk.">
<div class="kicker">Where this came from</div>
<div class="body center">
<h2>WhetstoneDSL</h2>
<p class="subtitle">AST-first programming and universal transpiling</p>
</div>
<div class="footer"><span>19</span><span>creation story</span></div>
</section>
<section class="slide" data-notes="Define taskitems in normal project-management language. This makes prereq_ops understandable.">
<div class="kicker">What a taskitem is</div>
<div class="body">
<ul class="bullets small-bullets">
<li>a small implementation work packet</li>
<li>title, requirements, constraints</li>
<li>acceptance criteria and dependencies</li>
</ul>
</div>
<div class="footer"><span>20</span><span>work packet</span></div>
</section>
<section class="slide" data-notes="A taskitem is not just text. Before it runs, the pipeline needs to decide what prep work is required.">
<div class="kicker">Taskitems need prep decisions</div>
<div class="body center">
<h2>What has to happen before this task runs?</h2>
</div>
<div class="footer"><span>21</span><span>the gate question</span></div>
</section>
<section class="slide" data-notes="This is the WhetstoneDSL gate in plain English. Avoid saying prereq_op first; say prep checklist first.">
<div class="kicker">The prep checklist</div>
<div class="body">
<ul class="bullets small-bullets">
<li>validate the intake</li>
<li>resolve dependencies</li>
<li>send to architect review</li>
</ul>
</div>
<div class="footer"><span>22</span><span>small yes/no decisions</span></div>
</section>
<section class="slide" data-notes="Now give the technical gate name after the audience understands the decision.">
<div class="kicker">In the repo</div>
<div class="body center">
<h2><code>prereq_op_selector</code></h2>
<p class="subtitle">picks the prerequisite operations for a taskitem</p>
</div>
<div class="footer"><span>23</span><span>technical name</span></div>
</section>
<section class="slide" data-notes="This is the tiny-transformer approach in one sentence.">
<div class="kicker">Tiny transformer gate</div>
<div class="body center">
<h2>Learn the messy input.</h2>
<p class="subtitle">Keep the output menu fixed.</p>
</div>
<div class="footer"><span>24</span><span>middle path</span></div>
</section>
<section class="slide" data-notes="This is your actual hardware and training-time number. This makes the project feel grounded.">
<div class="kicker">Actual training cost</div>
<div class="body center">
<div>
<div class="metric"><strong>3 to 5</strong><span>minutes</span></div>
<div class="metric"><strong>3060</strong><span>RTX GPU</span></div>
</div>
<p class="subtitle">per transformer gate</p>
</div>
<div class="footer"><span>25</span><span>consumer hardware</span></div>
</section>
<section class="slide" data-notes="This is the cost inversion. API calls charge every time. A trained local gate is a one-time training cost plus local electricity and hardware use.">
<div class="kicker">Local gate cost shape</div>
<div class="body center">
<pre><code>10 planning gates
x 3 to 5 minutes each
= ~30 to 50 minutes one-time training
then local inference</code></pre>
</div>
<div class="footer"><span>26</span><span>train once, reuse</span></div>
</section>
<section class="slide" data-notes="Use this carefully: it is a pessimistic proxy because inference is faster than training. It still makes the point that hundreds or thousands of decisions are not scary locally.">
<div class="kicker">Decision runtime intuition</div>
<div class="body center">
<pre><code>training speed proxy:
4000 steps / 3 to 5 min
= ~13 to 22 steps/sec
1,650 planning decisions
= minutes, not token invoices</code></pre>
</div>
<div class="footer"><span>27</span><span>pessimistic proxy</span></div>
</section>
<section class="slide" data-notes="These are the actual model-scale numbers from the WhetstoneRSA materials.">
<div class="kicker">Actual model scale</div>
<div class="body center">
<div>
<div class="metric"><strong>213K</strong><span>parameters</span></div>
<div class="metric"><strong>800KB</strong><span>checkpoint</span></div>
</div>
<p class="subtitle">one specialist per small gate</p>
</div>
<div class="footer"><span>26</span><span>the whole model is small</span></div>
</section>
<section class="slide" data-notes="The data was bootstrapped while using an LLM. That is a feature of the story: use the LLM to create scaffolding, then remove it from repeated runtime.">
<div class="kicker">Training data source</div>
<div class="body center">
<h2>LLM as scaffolding.</h2>
<p class="subtitle">Use it to bootstrap examples, not to sit in every runtime decision.</p>
</div>
<div class="footer"><span>27</span><span>distill repeated decisions</span></div>
</section>
<section class="slide" data-notes="Synthetic data matters because small gates are easy to intentionally vary. You can oversample edge cases and phrase variants.">
<div class="kicker">Synthetic data can help</div>
<div class="body">
<ul class="bullets small-bullets">
<li>generate taskitem variants</li>
<li>assign known labels</li>
<li>oversample edge cases</li>
<li>train the tiny gate directly</li>
</ul>
</div>
<div class="footer"><span>28</span><span>cheap dataset iteration</span></div>
</section>
<section class="slide" data-notes="These are the actual extraction numbers. Keep them short.">
<div class="kicker">First extracted dataset</div>
<div class="body center">
<div>
<div class="metric"><strong>1297</strong><span>clean rows</span></div>
<div class="metric"><strong>1102</strong><span>train</span></div>
<div class="metric"><strong>195</strong><span>eval</span></div>
</div>
</div>
<div class="footer"><span>29</span><span>real pipeline artifacts</span></div>
</section>
<section class="slide" data-notes="This is an important engineering lesson. One of the supposed model outputs was actually a constant rule.">
<div class="kicker">The data caught a design mistake</div>
<div class="body center">
<h2><code>needs_validate_intake</code></h2>
<p class="subtitle">was always true: <span class="accent">1297 / 1297</span></p>
</div>
<div class="footer"><span>30</span><span>not a learned decision</span></div>
</section>
<section class="slide" data-notes="So the gate was split into smaller gates. This is a good result: cheap experiments reveal better architecture.">
<div class="kicker">Split the gate</div>
<div class="body center">
<div class="flow two">
<div class="box cyan"><div class="label">Gate 1</div><div class="main">resolve dependencies?</div></div>
<div class="box blue"><div class="label">Gate 2</div><div class="main">architect review?</div></div>
</div>
</div>
<div class="footer"><span>31</span><span>smaller decisions</span></div>
</section>
<section class="slide" data-notes="The results are not production-ready. Say that directly. The point is that the experiment cost was so low that failure is informative.">
<div class="kicker">First results</div>
<div class="body center">
<table class="table">
<tr><th>Gate</th><th>Accuracy</th><th>Training</th></tr>
<tr><td>resolve dependencies</td><td>69.4%</td><td>3-5 min on 3060</td></tr>
<tr><td>architect review</td><td>75.0%</td><td>3-5 min on 3060</td></tr>
</table>
</div>
<div class="footer"><span>32</span><span>diagnostic, not a victory lap</span></div>
</section>
<section class="slide" data-notes="This explains why the first results were weak without making the project sound weak. The input fields were not designed for this classifier.">
<div class="kicker">What we learned</div>
<div class="body center">
<h2>1297 rows did not mean 1297 different examples.</h2>
<p class="subtitle">There were only about <span class="accent">17 unique text templates</span>.</p>
</div>
<div class="footer"><span>33</span><span>row count is not diversity</span></div>
</section>
<section class="slide" data-notes="This is the central comparison slide. The message is not that tiny transformers always win. It is that they are a real middle option.">
<div class="kicker">The comparison</div>
<div class="body center">
<table class="table">
<tr><th>Approach</th><th>Input handling</th><th>Runtime</th><th>Output control</th></tr>
<tr><td>Regex</td><td>manual enumeration</td><td>tiny</td><td>excellent</td></tr>
<tr><td>LLM / SLM + LoRA</td><td>easy</td><td>base model still runs</td><td>needs guardrails</td></tr>
<tr><td>Tiny gate transformer</td><td>learned</td><td>~800KB specialist</td><td>fixed output head</td></tr>
</table>
</div>
<div class="footer"><span>34</span><span>the middle path</span></div>
</section>
<section class="slide" data-notes="End with the clean contrast. This is the line to remember.">
<div class="kicker">Final claim</div>
<div class="body center">
<div class="stack">
<div class="bigline">AST-first gets the program out fast.</div>
<div class="bigline"><span class="accent">RSA makes the repeated planning local.</span></div>
</div>
</div>
<div class="footer"><span>35</span><span>small menu, small machine</span></div>
</section>
<section class="slide" data-notes="Keep this available if someone challenges the numbers. It shows which numbers are measured locally and which are estimates.">
<div class="kicker">Number sources</div>
<div class="body">
<ul class="bullets small-bullets">
<li>taskitem counts: extracted WhetstoneRSA rows</li>
<li>10+ decisions/taskitem: pipeline audit</li>
<li>3 to 5 min/gate: RTX 3060 training run</li>
<li>API prices: OpenAI model docs, Apr 2026</li>
</ul>
</div>
<div class="footer"><span>36</span><span>measured vs estimated</span></div>
</section>
<section class="slide" data-notes="This is the crisp ending: product spec to program is the experience; local gates are how the economics and repeatability improve over time.">
<div class="kicker">End state</div>
<div class="body center">
<h2>Product spec in.</h2>
<h2><span class="accent">Program out.</span></h2>
<p class="subtitle">Faster, cheaper, more predictable each time the gates move local.</p>
</div>
<div class="footer"><span>36</span><span>the product promise</span></div>
</section>
</div>
<div class="hint">Click / arrows: navigate · N: notes · F: fullscreen</div>
<div class="notes" id="notes"></div>
<div class="progress" id="progress"></div>
<script>
const slides = Array.from(document.querySelectorAll(".slide"));
const notes = document.getElementById("notes");
const progress = document.getElementById("progress");
let index = 0;
let notesVisible = false;
function indexFromHash() {
const raw = window.location.hash.replace("#", "");
const requested = Number(raw);
if (Number.isInteger(requested) && requested >= 1 && requested <= slides.length) {
index = requested - 1;
}
}
function render(updateHash = true) {
slides.forEach((slide, i) => slide.classList.toggle("active", i === index));
slides.forEach((slide, i) => {
const numberSlot = slide.querySelector(".footer span:first-child");
if (numberSlot) numberSlot.textContent = String(i + 1);
});
progress.style.width = `${((index + 1) / slides.length) * 100}%`;
notes.innerHTML = `<strong>Speaker notes:</strong><br>${slides[index].dataset.notes || ""}`;
notes.classList.toggle("visible", notesVisible);
document.title = `(${index + 1}/${slides.length}) WhetstoneRSA`;
if (updateHash) {
history.replaceState(null, "", `#${index + 1}`);
}
}
function next() {
index = Math.min(slides.length - 1, index + 1);
render();
}
function prev() {
index = Math.max(0, index - 1);
render();
}
document.addEventListener("click", (event) => {
if (event.target.closest(".notes")) return;
next();
});
document.addEventListener("keydown", (event) => {
if (event.key === "ArrowRight" || event.key === "PageDown" || event.key === " ") {
event.preventDefault();
next();
} else if (event.key === "ArrowLeft" || event.key === "PageUp" || event.key === "Backspace") {
event.preventDefault();
prev();
} else if (event.key.toLowerCase() === "n") {
notesVisible = !notesVisible;
render();
} else if (event.key.toLowerCase() === "f") {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen();
} else {
document.exitFullscreen();
}
}
});
window.addEventListener("hashchange", () => {
indexFromHash();
render(false);
});
indexFromHash();
render(false);
</script>
</body>
</html>