<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://aftershock.redoubtlabs.dev/feed.xml" rel="self" type="application/atom+xml" /><link href="https://aftershock.redoubtlabs.dev/" rel="alternate" type="text/html" /><updated>2026-09-19T04:45:06+00:00</updated><id>https://aftershock.redoubtlabs.dev/feed.xml</id><title type="html">Aftershock — Field Log</title><subtitle>The build journey of Aftershock — a disaster-response society of Qwen agents, named a Winner (Top 10 Honorable Mention Projects) in the Global AI Hackathon Series with Qwen Cloud. The claims that survived scrutiny: written doctrine lifts protocol conformance (credible at p=0.031; 95% on the NYC-Ida demo run) and six small models out-deliver one big one at ~65% better lives-per-dollar — plus the negative results, and the lives headline we firmed and walked back, that got us to the honest numbers.</subtitle><author><name>Kenny Ademolu</name></author><entry><title type="html">We only ever tested Qwen. So we ran the headline against eleven other models — and had to correct how we say it</title><link href="https://aftershock.redoubtlabs.dev/2026/07/01/we-only-ever-tested-qwen.html" rel="alternate" type="text/html" title="We only ever tested Qwen. So we ran the headline against eleven other models — and had to correct how we say it" /><published>2026-07-01T16:00:00+00:00</published><updated>2026-07-01T16:00:00+00:00</updated><id>https://aftershock.redoubtlabs.dev/2026/07/01/we-only-ever-tested-qwen</id><content type="html" xml:base="https://aftershock.redoubtlabs.dev/2026/07/01/we-only-ever-tested-qwen.html"><![CDATA[<p>In the last two logs I wrote that six cheap Qwen models with a protocol out-deliver one big model
(Log 009), and — last log — that paying 10× for a bigger model buys nothing the outcome can see
(Log 010). A reader asked the obvious, fair question: <strong>every model you’ve ever run is a Qwen. How do
you know this isn’t a Qwen thing?</strong></p>

<p>They’re right that it’s the load-bearing objection. If the only “big model” you ever test is
<code class="language-plaintext highlighter-rouge">qwen3-max</code>, “a society beats a big model” could just mean “our society beats one <em>particular family’s</em>
flagship.” The honest way to find out is to run the claim against the actual frontier — every family
you can reach — and see what survives. So that’s what I did. This entry is that test, and the small
correction it forced on how I say the result.</p>

<h2 id="getting-to-the-other-families">Getting to the other families</h2>

<p><a href="https://github.com/bluntmachetti/aftershock">Aftershock</a> talks to models through a single provider
chokepoint that was wired only for Alibaba’s DashScope (Qwen). The fix was small and additive: point
the whole stack at any OpenAI-compatible endpoint via one environment variable, and route through
<strong>OpenRouter</strong>, which serves every family behind one API. The one subtlety worth naming — because it’s
exactly the kind of thing that silently corrupts a benchmark — is that a couple of request fields we
send are <strong>Qwen-specific</strong> (<code class="language-plaintext highlighter-rouge">enable_thinking</code>, and a self-hosted reasoning toggle). Send those to a
strict router in front of GPT-5 and it can reject the call. So the new path keeps those fields <em>off</em>
the non-Qwen hosts, and the DashScope request body stays <strong>byte-identical</strong> to what it was. I also
smoke-tested every model against the JSON decision contract before spending a cent, and made the cost
ledger read real per-model prices so lives-per-dollar stays honest across families.</p>

<p>Then the experiment: the <strong><code class="language-plaintext highlighter-rouge">solo</code> arm</strong> — one model runs the entire town, no protocol — on twelve
models from ten families, ten paired seeds each, against the same cheap all-flash Qwen <strong>society</strong>
(six <code class="language-plaintext highlighter-rouge">qwen3.5-flash</code> workers + the auction + doctrine) that has anchored this whole log:
<strong>106.0 lives saved, $0.025 a run, 4272 lives per dollar.</strong></p>

<h2 id="what-the-twelve-models-did">What the twelve models did</h2>

<div class="readout-table">
  <div class="rt-cap"><span class="sq"></span>solo arm, 10 paired seeds, vs the cheap Qwen society (106.0 lives · $0.025 · 4272 lives/$)</div>
  <table class="rt">
    <thead><tr><th>Model (solo)</th><th>Family</th><th>Lives</th><th>Cost</th><th>Lives/$</th><th>Δ vs society</th></tr></thead>
    <tbody>
      <tr><td>GPT-5</td><td>US frontier</td><td>107.6</td><td>$0.340</td><td>317</td><td>+1.6 <span class="muted">(p=1.00)</span></td></tr>
      <tr><td>Gemini 3.1 Pro</td><td>US frontier</td><td>109.0</td><td>$0.356</td><td>306</td><td>+3.0 <span class="muted">(p=0.51)</span></td></tr>
      <tr><td>Claude Opus 4.8</td><td>US frontier</td><td>108.0</td><td>$0.313</td><td>345</td><td>+2.0 <span class="muted">(p=0.29)</span></td></tr>
      <tr><td>Grok 4.3</td><td>US frontier</td><td>106.0</td><td>$0.075</td><td>1408</td><td>+0.0 <span class="muted">(p=0.75)</span></td></tr>
      <tr><td>DeepSeek V4 Pro</td><td>CN frontier</td><td>104.0</td><td>$0.029</td><td>3551</td><td>−2.0 <span class="muted">(p=0.75)</span></td></tr>
      <tr><td>DeepSeek V4 Flash</td><td>CN frontier</td><td>103.4</td><td>$0.006</td><td><strong>17782</strong></td><td>−2.6 <span class="muted">(p=0.51)</span></td></tr>
      <tr><td>Kimi K2.7</td><td>CN frontier</td><td>101.6</td><td>$0.076</td><td>1345</td><td>−4.4 <span class="muted">(p=1.00)</span></td></tr>
      <tr><td>GLM 5.2</td><td>CN frontier</td><td>105.4</td><td>$0.066</td><td>1595</td><td>−0.6 <span class="muted">(p=0.51)</span></td></tr>
      <tr class="win"><td><strong>cheap Qwen society</strong></td><td>—</td><td><strong>106.0</strong></td><td><strong>$0.025</strong></td><td><strong>4272</strong></td><td>—</td></tr>
      <tr class="lose"><td>Mistral Large</td><td>open-weight</td><td>95.1</td><td>$0.023</td><td>4114</td><td>−10.9 <span class="muted">(p=0.002)</span></td></tr>
      <tr class="lose"><td>Llama 3.3 70B</td><td>open-weight</td><td>97.7</td><td>$0.004</td><td>28141</td><td>−8.3 <span class="muted">(p=0.29)</span></td></tr>
      <tr class="lose"><td>Qwen3 235B</td><td>open-weight</td><td>79.7</td><td>$0.003</td><td>27638</td><td>−26.3 <span class="muted">(p=0.002)</span></td></tr>
      <tr class="lose"><td>Llama 3.1 8B</td><td>floor</td><td>24.6</td><td>$0.001</td><td>32958</td><td>−81.4 <span class="muted">(p=0.002)</span></td></tr>
    </tbody>
  </table>
</div>

<p>The headline is the top block. <strong>No single model’s solo beats the cheap six-flash society on lives.</strong>
The eight frontier-class models — four American, four Chinese — land at 102–109 lives, every paired
sign test at p ≥ 0.29, which at ten seeds with a standard deviation near sixteen is
<em>indistinguishable from the society</em>. And they pay for the tie: 3–14× the cost, 306–1595 lives per
dollar against the society’s 4272.</p>

<h2 id="the-correction-i-owe">The correction I owe</h2>

<p>Here’s the part I have to be straight about, because the cross-family run doesn’t just confirm the old
story — it <em>corrects</em> it. When the only big model I’d tested was <code class="language-plaintext highlighter-rouge">qwen3-max</code>, its solo sat down at the
swarm’s anarchy floor (a finding from a few logs back). That made it easy — too easy — to say
“coordination beats a big model,” and to let that sound like a claim about <em>lives</em>.</p>

<p>Cross-family, that phrasing is too strong. A genuine frontier solo — GPT-5, Gemini 3.1 Pro, Opus 4.8,
Grok, and DeepSeek V4 and GLM behind them — <strong>does reach the coordination ceiling on the outcome.</strong> It
ties the society on lives. So the honest version isn’t “coordination beats a big model.” It’s: <strong>a
big-enough model’s solo matches the cheap coordinated society on the outcome, and the society’s win is
on cost — up to ~14× on lives-per-dollar against the flagship frontiers (a slimmer margin against the
cheaper ones) — and it holds, in direction, across ten families.</strong> That’s a narrower
claim than I’d been implying, and it’s the true one.</p>

<p>And there’s one honest dent I won’t bury: <strong>DeepSeek V4 Flash</strong> ties the society on lives <em>and</em> beats
it on cost — 103.4 lives at $0.006 a run, four times the society’s lives-per-dollar. A cheap enough,
good enough single model can win the cost argument too. It’s one model out of twelve, and the society’s
edge is robust across the whole board, but “coordination always wins on cost” would be an overclaim, so:
it doesn’t, quite.</p>

<h2 id="what-didnt-tie">What didn’t tie</h2>

<p>Below the frontier, the picture is exactly the capability story you’d hope a good ruler shows. Mistral
Large lands 11 lives short (p=0.002), Qwen3-235B twenty-six short (p=0.002), and the <strong>Llama-3.1-8B
floor collapses</strong> to 24.6 lives — losing every one of the ten seeds — echoing the 1.7B collapse I found
self-hosting earlier. There’s a real competence threshold to <em>operate the town at all</em>, and it sits
somewhere above 8B and below the frontier, consistently, across families. That’s the other half of the
robustness result: the substrate cleanly separates models that can do the job from models that can’t,
and it does it the same way regardless of who trained them.</p>

<h2 id="the-honest-bounds">The honest bounds</h2>

<p>Three, as ever. <strong>The runs aren’t byte-reproducible</strong> — the LLM layer never was (the provider ignores
our sampling seed), so this is independent-seed inference, and I pair every model against the society by
seed to cancel the world draw. <strong>The prompts are Qwen-tuned</strong> — they were written and iterated against
Qwen, so a non-Qwen model that scores a little lower is partly being judged on prompt fit, not raw
capability; the mitigation is that all twelve parsed the JSON contract cleanly, and the <em>frontier tie</em>
(the load-bearing result) doesn’t depend on it. And <strong>the prices drift</strong> — these are OpenRouter list
prices on the day, so read lives-per-dollar as an order-of-magnitude, not a decimal. One model-choice
note: the only Kimi 2.7 on the router was the <em>code-specialized</em> build, which is a worse fit for a
decision task and ran ~10× slower — but it still tied within noise, so it doesn’t move the verdict.</p>

<p>The whole thing cost about <strong>$14.50</strong>. That number is itself a small argument for the finding: I
stress-tested the central claim of the project against every frontier model I could reach — GPT-5 to
DeepSeek V4 — for the price of a sandwich, because the honest outcome metric is cheap to measure and the
society it’s being compared against runs on models that cost fractions of a cent.</p>

<p>So: the reader was right to push, and the claim is better for it. <strong>Six cheap coordinated models match
any single frontier model’s outcome — at up to a tenth of the flagship’s cost — and that holds across
ten families, not one.</strong> It’s not the flashier “the small society beats the big model.” It’s the true
one, and now it’s the one I’ll say.</p>

<p>One more data point, for anyone keeping score across projects: a sibling research effort of mine,
<a href="https://blog.redoubtlabs.dev/arena/">Redoubt Arena</a>, ran the same kind of check on a completely
different simulated world — an enterprise-resilience mission instead of a disaster response — sweeping
15 models against a deterministic recovery baseline. Same shape of result: zero model runs beat the
baseline outright; strong models only tie it. Different domain, same finding, twice now: a well-designed
non-LLM baseline is a harder bar to clear than it looks, and it’s worth measuring before assuming an LLM
adds value.</p>

<p>Live demo: <strong><a href="https://aftershock.redoubtlabs.dev">https://aftershock.redoubtlabs.dev</a></strong> · Code: <strong><a href="https://github.com/bluntmachetti/aftershock">https://github.com/bluntmachetti/aftershock</a></strong>
(method + verdict in <code class="language-plaintext highlighter-rouge">docs/FIELD-NOTES.md</code> §28; data under <code class="language-plaintext highlighter-rouge">bench/results/2026-07-01-panelA-solo/</code>)</p>]]></content><author><name>Kenny Ademolu</name></author><summary type="html"><![CDATA[Every claim in this log rides on Qwen models, so the fair critique is: is 'a cheap coordinated society beats one big model' just a Qwen artifact? To answer it I built a family-agnostic provider path (one OpenRouter endpoint, any family, Qwen-only request fields kept off the non-Qwen hosts) and ran the solo arm — one model runs the whole town — on twelve models from ten families: GPT-5, Gemini 3.1 Pro, Claude Opus 4.8, Grok 4.3, DeepSeek V4 Pro/Flash, Kimi K2.7, GLM 5.2, Qwen3-235B, Llama-3.3-70B, Mistral Large, and a Llama-3.1-8B floor. Result: no single model's solo beats the cheap six-flash Qwen society on lives — but the eight frontier models (US and Chinese) TIE it, at 3-14x the cost. That forced an honest correction: earlier, on Qwen-only data, a big Qwen solo sat at the swarm's anarchy floor, which made 'coordination beats a big model' sound like a lives claim. Cross-family it isn't — a genuine frontier solo reaches the outcome ceiling. The society's win is on cost-efficiency, and it holds across ten families. Plus the honest dent (a cheap DeepSeek V4 Flash that ties on lives and beats on cost) and a clean cross-family capability floor.]]></summary></entry><entry><title type="html">We paid 10× for a bigger model and saved zero extra lives — then watched coordination backfire when nothing was scarce</title><link href="https://aftershock.redoubtlabs.dev/2026/06/30/bigger-model-same-lives-scarcity-is-the-game.html" rel="alternate" type="text/html" title="We paid 10× for a bigger model and saved zero extra lives — then watched coordination backfire when nothing was scarce" /><published>2026-06-30T16:00:00+00:00</published><updated>2026-06-30T16:00:00+00:00</updated><id>https://aftershock.redoubtlabs.dev/2026/06/30/bigger-model-same-lives-scarcity-is-the-game</id><content type="html" xml:base="https://aftershock.redoubtlabs.dev/2026/06/30/bigger-model-same-lives-scarcity-is-the-game.html"><![CDATA[<p>Most of these logs report one experiment. This one reports two, because they turned out to be the
same finding wearing two costumes — and because they came from the same place: a pair of open
questions I’d been carrying around from a larger project on agent-run <em>organisations</em>. That project
has a frustrating property — its main outcome signal is swamped by background noise, so it struggles
to tell <em>“the agent made a good call”</em> apart from <em>“the environment would have carried any agent.”</em>
<a href="https://github.com/bluntmachetti/aftershock"><strong>Aftershock</strong></a> has the opposite property, and it’s the
whole reason it exists: its outcome is <strong>lives saved</strong>, a conserved quantity with no hidden subsidy.
Every imperiled life is saved, lost, or still-open — an identity, not a model. So I brought the two
questions here, where the substrate can’t do the agent’s job for it.</p>

<h2 id="question-1-does-a-bigger-model-decide-better">Question 1: does a bigger model decide better?</h2>

<p>This is the question that gates real money. If a larger C-suite model makes materially better
decisions, you rent GPUs. If it doesn’t, you don’t. So you want to answer it <em>before</em> the hardware
PO, on cheap hosted inference.</p>

<p>Aftershock’s society runs six role agents — a commander plus medical, rescue, fire, infrastructure,
comms. The default roster is mostly cheap <code class="language-plaintext highlighter-rouge">qwen3.5-flash</code> workers. I held everything byte-fixed — the
seeded world, the auction, the doctrine — and swapped <strong>all six roles</strong> across three price tiers via
a single flag (<code class="language-plaintext highlighter-rouge">bench --role-model</code>), ten paired seeds, sixty ticks each:</p>

<div class="readout-table">
  <div class="rt-cap"><span class="sq"></span>Whole-roster model-tier sweep (society arm, 10 paired seeds)</div>
  <table class="rt">
    <thead><tr><th>Tier (all six roles)</th><th>Lives saved</th><th>Conformance</th><th>Cost / run</th><th>Lives per $</th></tr></thead>
    <tbody>
      <tr class="win"><td><strong>qwen3.5-flash</strong> (0.10 / 0.40)</td><td>106.0 ±16.9</td><td>0.872</td><td>$0.0248</td><td><strong>4272</strong></td></tr>
      <tr><td>qwen3.5-plus (0.40 / 2.40)</td><td>107.5 ±17.0</td><td>0.890</td><td>$0.0892</td><td>1205</td></tr>
      <tr class="lose"><td>qwen3-max (1.20 / 6.00)</td><td>107.0 ±16.6</td><td>0.879</td><td>$0.2404</td><td><strong>445</strong></td></tr>
    </tbody>
  </table>
</div>

<p><strong>Lives are flat.</strong> Every pairwise paired delta is statistical noise: plus over flash is +1.5 (sign
test p=0.754), max over flash is +1.0 (p=1.000), max over plus is −0.5 (p=0.453) — all dwarfed by a
per-seed standard deviation of ~17. Conformance barely moves (0.872 → 0.890 → 0.879). Meanwhile cost
rises <strong>9.7×</strong> and lives-per-dollar <strong>collapses 9.6×</strong>.</p>

<p>The tell is in the per-seed rows. On seed 11 the three tiers saved 140 / 136 / 136 lives; on seed
127, 83 / 82 / 82; on seed 73, 126 / 131 / 130. The model you pick barely shifts the outcome — the
<strong>world you draw</strong> sets it. (That matches what we measured back in Log 004: the world accounts for
~79% of the variance between runs. The model tier is rounding error against it.)</p>

<p>This isn’t “models don’t matter.” An earlier self-hosted size sweep (recorded in
<code class="language-plaintext highlighter-rouge">docs/FIELD-NOTES.md</code> §22) had a <em>too-small</em> model — 1.7B — collapse to zero lives saved: there’s a
<strong>capability floor</strong>, and below it model size is everything. The finding is
that <strong>once your roster clears that floor, paying more buys nothing the outcome can see.</strong> And the
cheap lever we already shipped — <em>written doctrine</em>, which lifts protocol conformance by a credible
+0.125 (p=0.031) at <strong>zero</strong> extra cost — moves exactly what a 10× model spend couldn’t. The verdict
is a clean <strong>KILL</strong>: no GPU capex is justified for this task; spend the budget on the harness, not the
model.</p>

<h2 id="question-2-when-does-coordination-actually-matter">Question 2: when does coordination actually matter?</h2>

<p>The running theme of this whole log is <em>a coordinated society of small models versus an uncoordinated
swarm</em>, scored last week as a <a href="https://bluntmachetti.github.io/aftershock/">price of anarchy</a> — the
efficiency a resource scramble leaves on the table. But I’d only ever measured it at <strong>one</strong> level of
scarcity. The open question is whether the coordination advantage is a constant, or whether it
<em>depends on the friction</em>. Theory has a strong prior here: with no congestion there’s no externality,
so there should be nothing for a coordination mechanism to fix.</p>

<p>So I swept it. Same seeded world, same arms, varying only the resource abundance — a uniform pool
ladder from <strong>12 of each unit (abundance)</strong> down to <strong>1 (famine)</strong> — running the coordinated arms
(<code class="language-plaintext highlighter-rouge">scripted</code> central heuristic, <code class="language-plaintext highlighter-rouge">society</code> auction) against the uncoordinated <code class="language-plaintext highlighter-rouge">swarm</code>. Eight paired
seeds per level. Efficiency = fraction of imperiled lives saved:</p>

<div class="readout-table">
  <div class="rt-cap"><span class="sq"></span>Coordination efficiency vs resource scarcity (8 paired seeds/level)</div>
  <table class="rt">
    <thead><tr><th>Pool / unit</th><th>scripted</th><th>society</th><th>swarm</th><th>society − swarm</th><th>Price of anarchy</th><th>sign test</th></tr></thead>
    <tbody>
      <tr class="lose"><td><strong>12 — abundance</strong></td><td>73.9%</td><td>73.7%</td><td><strong>79.3%</strong></td><td><strong>−5.6 pt</strong></td><td>0.93</td><td><strong>0/8, p=0.008</strong></td></tr>
      <tr><td>6</td><td>72.4%</td><td>72.1%</td><td>72.3%</td><td>−0.1 pt</td><td>1.00</td><td>3/8, p=0.727</td></tr>
      <tr class="win"><td>4 — ≈ default</td><td>69.2%</td><td>68.0%</td><td>61.9%</td><td>+6.1 pt</td><td>1.10</td><td>6/8, p=0.289</td></tr>
      <tr class="win"><td><strong>2</strong></td><td>50.7%</td><td>47.1%</td><td>39.7%</td><td><strong>+7.3 pt</strong></td><td><strong>1.18</strong></td><td>6/8, p=0.289</td></tr>
      <tr><td>1 — famine</td><td>23.6%</td><td>20.1%</td><td>19.9%</td><td>+0.2 pt</td><td>1.01</td><td>4/8, p=1.000</td></tr>
    </tbody>
  </table>
</div>

<p>The coordination advantage is an <strong>inverted-U, gated entirely by friction</strong> — and the surprising end
is the <em>top</em> of the table. <strong>At abundance, coordinating is net-harmful.</strong> With units lying around
unused, the auction is pure overhead: the uncoordinated swarm just grabs what it needs and saves
<em>more</em> lives (79.3% vs the society’s 73.7%), winning on <strong>all 8 seeds, p=0.008</strong> — the single
strongest result in the whole sweep. Coordination only starts paying once contention appears: it
pulls ahead through moderate scarcity, peaking at pool=2 (+7.3 points, a 1.18× price of anarchy).
Then at the famine floor everyone collapses to ~20% and the gap vanishes — when nothing can be saved,
there’s nothing to arbitrate.</p>

<p>The diagnostics confirm the mechanism rather than just the outcome. Contested resource losses climb
monotonically as pools tighten — 12 → 222 → 612 → 1424 — and <strong>priority inversions stay at exactly
zero until the famine level</strong> (then 26), which is its own small corroboration of Log 004: the auction
allocates soundly right up to the point where the problem becomes unwinnable.</p>

<h2 id="the-two-costumes-same-body">The two costumes, same body</h2>

<p>Put the two experiments side by side and they say one thing. In Question 1, across a 10× span of
model price, <strong><code class="language-plaintext highlighter-rouge">scripted</code> and <code class="language-plaintext highlighter-rouge">society</code> track each other</strong> — the hand-tuned heuristic and the LLM
society are within noise. In Question 2, across the entire scarcity ladder, they track each other
<em>again</em>: 73.9/73.7, 72.4/72.1, 69.2/68.0, 50.7/47.1, 23.6/20.1. Whether the deciders are heuristics
or a six-model society, and whether those models are cheap or expensive, barely registers.</p>

<p>What registers is <strong>the coordination mechanism, and only when the world is contended enough to need
it.</strong> The lever isn’t model quality and it isn’t even “LLM vs hand-tuned” — it’s <em>structure under
scarcity</em>. Spend your effort there.</p>

<h2 id="what-stays-suggestive-and-what-doesnt">What stays suggestive, and what doesn’t</h2>

<p>The honest bookkeeping, because over-claiming is the fastest way to lose a reader’s trust (Log 006
taught us that the hard way).</p>

<p>The <strong>abundance reversal is significant</strong> — society loses all eight seeds, p=0.008. But the
<strong>coordination <em>wins</em> in the middle of the curve are suggestive, not significant</strong>: +6 to +7 points
is real-looking, but at eight seeds the sign test sits at p=0.289. That’s the same caveat the raw
society-vs-swarm edge has carried for three logs now, and a uniform pool ladder doesn’t dissolve it —
it would take more seeds at the pool=2 sweet spot to firm it. And Question 1’s flat result is a
<em>null</em> at n=10 with σ≈17, so it rules out a large model-tier effect on lives, not a tiny one — but a
flat line across a 10× price span, with no tier ordering, is itself the finding.</p>

<p>Two clean, reproducible results, then, with their uncertainty stated: bigger models don’t decide
better above the floor, and coordination is worth nothing — sometimes worse than nothing — until the
resources get scarce. Both point the same way, and both came from asking a sister project’s question
on a substrate honest enough to answer it.</p>

<p>Build the ruler first, as ever. Then let it tell you where the money <em>isn’t</em> worth spending.</p>

<p>Live demo: <strong><a href="https://aftershock.redoubtlabs.dev">https://aftershock.redoubtlabs.dev</a></strong> · Code: <strong><a href="https://github.com/bluntmachetti/aftershock">https://github.com/bluntmachetti/aftershock</a></strong>
(method + verdicts in <code class="language-plaintext highlighter-rouge">docs/FIELD-NOTES.md</code> §26–§27; data under <code class="language-plaintext highlighter-rouge">bench/results/2026-06-30-*</code>)</p>

<hr />

<h3 id="related-work">Related work</h3>

<p><em>Checked before publishing (Log 006’s lesson). The game-theory framing under Question 2 is the same
literature Log 009 drew on; included here for the friction-necessity argument specifically.</em></p>

<ul>
  <li>Hardin, G. (1968). <em>The Tragedy of the Commons.</em> Science, 162(3859), 1243–1248. <a href="https://doi.org/10.1126/science.162.3859.1243">https://doi.org/10.1126/science.162.3859.1243</a> — no friction, no externality; the abundance row is the boundary case where the commons problem disappears.</li>
  <li>Rosenthal, R. W. (1973). <em>A class of games possessing pure-strategy Nash equilibria.</em> International Journal of Game Theory, 2, 65–67. <a href="https://doi.org/10.1007/BF01737559">https://doi.org/10.1007/BF01737559</a> — congestion games: the inefficiency is a function of the congestion.</li>
  <li>Koutsoupias, E. &amp; Papadimitriou, C. (1999). <em>Worst-Case Equilibria.</em> STACS ‘99, LNCS 1563, 404–413. <a href="https://doi.org/10.1007/3-540-49116-3_38">https://doi.org/10.1007/3-540-49116-3_38</a> — the price-of-anarchy ratio used as the y-axis above.</li>
  <li>Roughgarden, T. &amp; Tardos, É. (2002). <em>How Bad Is Selfish Routing?</em> Journal of the ACM, 49(2), 236–259. <a href="https://doi.org/10.1145/506147.506153">https://doi.org/10.1145/506147.506153</a> — the canonical result that uncoordinated play wastes a <em>bounded</em> factor, which the famine floor echoes (the gap re-compresses).</li>
</ul>]]></content><author><name>Kenny Ademolu</name></author><summary type="html"><![CDATA[Two open questions I'd been carrying from a larger agent-organisation project, run on Aftershock because it has something that project lacks: a conserved, subsidy-free outcome (lives saved). First: does a bigger C-suite model decide better? Swapping the whole six-role society from cheap qwen3.5-flash up through plus to qwen3-max over ten paired seeds, lives stay flat (106.0 → 107.5 → 107.0, every pairwise sign test p>0.45) while cost rises 9.7× and lives-per-dollar collapses 9.6×. Above the capability floor, model tier is outcome-neutral — a clean GPU-capex KILL. Second: when does coordination actually matter? Sweeping resource scarcity from abundance to famine, the society-vs-swarm advantage is an inverted-U gated by friction: at abundance coordination is net-HARMFUL (the uncoordinated swarm wins 79.3% vs 73.7%, society loses all 8 seeds, p=0.008), it peaks at moderate scarcity (price of anarchy 1.18×), and vanishes at the collapse floor. The through-line: scripted ≈ society at every tier and every scarcity level — the lever is coordination structure under contention, not model size.]]></summary></entry><entry><title type="html">We put a number on coordination: the price of anarchy in an agent society</title><link href="https://aftershock.redoubtlabs.dev/2026/06/26/the-price-of-anarchy.html" rel="alternate" type="text/html" title="We put a number on coordination: the price of anarchy in an agent society" /><published>2026-06-26T16:00:00+00:00</published><updated>2026-06-26T16:00:00+00:00</updated><id>https://aftershock.redoubtlabs.dev/2026/06/26/the-price-of-anarchy</id><content type="html" xml:base="https://aftershock.redoubtlabs.dev/2026/06/26/the-price-of-anarchy.html"><![CDATA[<p>A reader looked at the running theme of this log — <em>a coordinated society of small models versus an
uncoordinated swarm</em> — and asked the sharp question: <strong>isn’t that a Nash-equilibrium story? Does the
hypothesis actually hold if you frame it that way?</strong></p>

<p>It’s the best framing question I’ve gotten — and one I couldn’t resist, because I’m an economics and
game-theory geek at heart (my first degree was in Economics). That’s the honest reason this entry runs
longer and digs deeper into the theory than usual. Because it turns out <a href="https://github.com/bluntmachetti/aftershock"><strong>Aftershock</strong></a>
isn’t <em>like</em> a game-theory problem — it <em>is</em> one, almost on the nose. So I spent today building a ruler
for it and reading the literature to make sure I was using the words correctly. This is what the ruler
said, what it can’t say yet, and where it points next.</p>

<h2 id="the-game-hiding-under-the-simulation">The game hiding under the simulation</h2>

<p>Strip the disaster theme away and Aftershock is a <strong>common-pool resource game</strong>. Each tick, six role
agents claim from finite shared pools — ambulances, rescue crews, fire engines, fuel — toward missions
that have a severity, a deadline, and lives at risk. Every claim one agent makes is a unit another agent
can’t use: a textbook <strong>negative externality</strong>. That is precisely the setting where game theory predicts
the <em>uncoordinated</em> outcome is inefficient — the classic <a href="https://doi.org/10.1126/science.162.3859.1243">tragedy of the commons</a>
(Hardin, 1968) — and where structure can claw the efficiency back. Elinor Ostrom’s Nobel-winning work
(<a href="https://doi.org/10.1017/CBO9780511807763"><em>Governing the Commons</em></a>, 1990) is the whole counter-argument:
communities don’t need privatization or a central state to avoid the tragedy; they need <em>institutions</em> —
shared rules everyone follows. That is a startlingly exact description of what we call <strong>doctrine</strong>.</p>

<p>The formal object for “players sharing congested resources” is a <strong>congestion game</strong>
(<a href="https://doi.org/10.1007/BF01737559">Rosenthal, 1973</a>), and the standard way to score how much selfish
play <em>costs</em> is the <strong>price of anarchy</strong> — the ratio between the social optimum and the worst
equilibrium — introduced as the “coordination ratio” by <a href="https://doi.org/10.1007/3-540-49116-3_38">Koutsoupias &amp; Papadimitriou (1999)</a>
and named by <a href="https://doi.org/10.1145/380752.380883">Papadimitriou (2001)</a>. The canonical worked example
is selfish routing, where <a href="https://doi.org/10.1145/506147.506153">Roughgarden &amp; Tardos (2002)</a> proved
uncoordinated traffic wastes at most a 4/3 factor with linear latencies. Swap “drivers on roads” for
“agents on ambulances” and you have our benchmark.</p>

<p>Our four arms line up on exactly the coordination axis:</p>

<div class="readout-table">
  <div class="rt-cap"><span class="sq"></span>The arms, as game-theory objects</div>
  <table class="rt">
    <thead><tr><th>Arm</th><th>Mechanism</th><th>Game-theory reading</th></tr></thead>
    <tbody>
      <tr class="lose"><td>swarm</td><td>flat agents, no arbitration (direct dispatch)</td><td>uncoordinated play — the price-of-anarchy baseline</td></tr>
      <tr class="lose"><td>solo</td><td>one big model deciding everything</td><td>centralized but single-headed</td></tr>
      <tr class="win"><td>society</td><td>per-tick auction + written doctrine</td><td>a mechanism + a correlation device</td></tr>
      <tr><td>scripted</td><td>hand-tuned central heuristic ($0)</td><td>a strong central planner</td></tr>
    </tbody>
  </table>
</div>

<p>The society’s auction is, literally, a piece of <strong>mechanism design</strong> — the field that runs from
<a href="https://doi.org/10.1111/j.1540-6261.1961.tb02789.x">Vickrey (1961)</a>, <a href="https://doi.org/10.1007/BF01726210">Clarke (1971)</a>
and <a href="https://www.jstor.org/stable/1914085">Groves (1973)</a> (the VCG family of efficient, strategyproof
allocation rules). And the doctrine is best read not as Nash but as a <strong>correlated equilibrium</strong>
(<a href="https://doi.org/10.1016/0304-4068(74)90037-8">Aumann, 1974</a>): a shared signal that all agents condition
on, which can beat what uncoordinated best-responses reach on their own.</p>

<h2 id="what-the-ruler-measured">What the ruler measured</h2>

<p>Raw “lives saved” is unbounded and trajectory-dependent, so it’s a poor yardstick for <em>efficiency</em>.
Instead I measured the <strong>fraction of imperiled lives saved</strong>, grounded in the sim’s own exact accounting:
every life that becomes at-risk is eventually saved, lost, or still-open, so</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>total_at_risk = lives_saved + lives_lost + open_remaining     (an identity, not a model)
efficiency    = lives_saved / total_at_risk                   (in [0, 1])
</code></pre></div></div>

<p>That’s <code class="language-plaintext highlighter-rouge">aftershock poa</code>, computed over recorded runs — deterministic, no API spend. Here is the result:</p>

<div class="readout-table">
  <div class="rt-cap"><span class="sq"></span>Efficiency = fraction of imperiled lives saved (4-arm benchmark, n=5)</div>
  <table class="rt">
    <thead><tr><th>Arm</th><th>Efficiency</th><th>Coordinated?</th></tr></thead>
    <tbody>
      <tr class="win"><td><strong>society</strong> (auction + doctrine)</td><td><strong>67.3%</strong></td><td>yes</td></tr>
      <tr class="win"><td>scripted (central heuristic)</td><td>66.2%</td><td>yes</td></tr>
      <tr class="lose"><td>solo (one big model)</td><td>58.9%</td><td>no</td></tr>
      <tr class="lose"><td>swarm (flat, no protocol)</td><td>58.1%</td><td>no</td></tr>
    </tbody>
  </table>
</div>

<p>The headline isn’t the top line — it’s the <strong>clustering</strong>. Both <em>coordinated</em> arms land at ~66–67%; both
<em>uncoordinated</em> arms land at ~58%. The structure, not the specific agent, is what moves the number. And
the sharpest data point in the whole project is hiding in that table: <strong>the expensive single big model
(solo) sits at the swarm’s anarchy level.</strong> For this allocation problem, <em>coordination beats raw model
size</em> — six cheap models with a protocol out-deliver one big model without one.</p>

<p>Pairing society against swarm directly, pooled to fifteen seeds:</p>

<div class="readout-table">
  <div class="rt-cap"><span class="sq"></span>society vs swarm, paired efficiency (n=15)</div>
  <table class="rt">
    <thead><tr><th>Stat</th><th>Value</th></tr></thead>
    <tbody>
      <tr><td>Mean efficiency delta</td><td><strong>+6.7 points</strong></td></tr>
      <tr><td>Seeds society won</td><td>11 / 15</td></tr>
      <tr><td>Bootstrap 95% CI</td><td>[+2.6, +10.8] (excludes 0)</td></tr>
      <tr class="lose"><td>Sign-test p</td><td>0.118 — <strong>suggestive, not significant</strong></td></tr>
      <tr><td>Price of anarchy (society / swarm)</td><td>1.11×</td></tr>
    </tbody>
  </table>
</div>

<p>So the swarm leaves roughly an eighth of the achievable lives on the table relative to the society — a
real price of anarchy — but the <em>pairwise</em> gap carries the same statistical caveat as the raw-lives
number two logs ago: the CI excludes zero, the sign test doesn’t clear significance. The efficiency
reframe is more <strong>interpretable</strong> (it’s bounded, and it cleanly separates coordinated from uncoordinated);
it does <strong>not</strong> manufacture significance, and I’m not going to pretend it does.</p>

<h2 id="what-i-cant-claim-and-why-im-saying-so">What I can’t claim (and why I’m saying so)</h2>

<p>Three honesty bounds, because the fastest way to discredit a game-theory framing is to over-reach with it.</p>

<p><strong>The agents are not equilibrium-solvers.</strong> They’re LLMs following prompts, not utility-maximizers
computing best responses. So “the society <em>reaches a Nash equilibrium</em>” is a category error — nobody is
solving a fixed point. The honest statement is that the <em>game</em> has an inefficient uncoordinated region
and an efficient coordinated one, and we measure where each arm’s <em>emergent</em> play lands. (The reason
this still works is one of my favorite results in the field: Roughgarden’s
<a href="https://theory.stanford.edu/~tim/papers/robust.pdf">smoothness framework</a> (2015) shows price-of-anarchy
bounds extend automatically to no-regret learning and correlated play — i.e., they bite even for messy,
non-equilibrium agents. That’s the bridge from the textbook to a swarm of language models.)</p>

<p><strong>The denominator is a ceiling, not a tight optimum.</strong> Efficiency = 1.0 means <em>every imperiled life
saved</em>. That’s a rigorous upper bound, but it is not the best <em>achievable</em> outcome under finite
resources — the true optimum is a multi-tick scheduling problem over the deterministic world, and it’s
intractable to compute exactly. So I report “fraction of saveable,” never “fraction of optimal.”</p>

<p><strong>On the hardest scenario, the order flips.</strong> On the brutal real-data NYC Hurricane Ida pack, the
scripted central heuristic saves 32.2% and the LLM society saves 8.9%. The coordination edge is a
<em>synthetic-benchmark</em> finding; the society is not magic on a savage real scenario. That belongs in the
same paragraph as the win, not in a footnote.</p>

<p>This is also why I keep one skeptical paper open on my desk: Cemri et al.’s
<a href="https://arxiv.org/abs/2503.13657"><em>Why Do Multi-Agent LLM Systems Fail?</em></a> (2025) catalogs how often
multi-agent LLM setups <em>underperform</em> — exactly the null hypothesis a “society beats X” claim has to
survive. Ours survives it structurally and suggestively, not decisively.</p>

<h2 id="the-experiments-that-would-firm-it">The experiments that would firm it</h2>

<p>A ruler is only useful if it tells you what to build next. Three follow-ups, in order of value:</p>

<ol>
  <li>
    <p><strong>A self-enforcement test.</strong> Right now we know the society’s allocation is <em>efficient</em> (it eliminates
priority inversions — see Log 004). We don’t know if it’s <em>stable</em>: could any single role do better by
deviating from the auction outcome? Replay each contested tick and check for a profitable unilateral
deviation. If there is none, the coordinated allocation is incentive-compatible — a self-enforcing
equilibrium, not merely an imposed rule. That’s the difference between “we told them to cooperate” and
“cooperating is their best move.”</p>
  </li>
  <li>
    <p><strong>A central-planner oracle for a tighter optimum.</strong> The save-everyone ceiling is loose. A strong
omniscient greedy planner run through the <em>same</em> deterministic engine would give an <em>achievable</em>
social-optimum proxy, turning “society reaches 67% of saveable” into “society reaches X% of what a
perfect coordinator achieves” — the real price-of-anarchy denominator.</p>
  </li>
  <li>
    <p><strong>Auction strategyproofness.</strong> Our auction allocates by urgency bids. Can an agent win contested units
by <em>overstating</em> urgency? The VCG line (<a href="https://doi.org/10.1111/j.1540-6261.1961.tb02789.x">Vickrey</a>/<a href="https://doi.org/10.1007/BF01726210">Clarke</a>/<a href="https://www.jstor.org/stable/1914085">Groves</a>)
is the theory of allocation rules where honesty is the dominant strategy. Testing whether doctrine
conformance keeps bids truthful — or whether a strategyproof rule does it for free — is a clean
mechanism-design question we already have the harness to answer.</p>
  </li>
</ol>

<h2 id="turning-the-lens-on-real-incident-response">Turning the lens on real incident response</h2>

<p>Here’s the part that makes this more than a benchmark curiosity. <strong>Real incident response already runs on
a coordination doctrine.</strong> The U.S. <a href="https://www.fema.gov/sites/default/files/2020-07/fema_nims_doctrine-2017.pdf">National Incident Management System</a>
(FEMA, 2017) and its Incident Command System exist <em>because</em> uncoordinated multi-agency response to a
disaster is a price-of-anarchy disaster: duplicated effort, contested resources, no clear allocation. ICS
is, in our vocabulary, the correlation device — a shared playbook that every responding unit conditions
on. Aftershock’s “doctrine” is a toy of exactly that idea.</p>

<p>And the resource problem under it is a well-studied optimization target: emergency dispatch and
ambulance routing/location have a large literature (see the reviews by
<a href="https://arxiv.org/abs/2006.04200">Mukhopadhyay et al., 2022</a> and
<a href="https://arxiv.org/abs/2001.05288">Tassone &amp; Choudhury, 2020</a>), and multi-agent disaster response has been
a grand challenge since <a href="https://doi.org/10.1609/aimag.v22i1.1542">RoboCup Rescue</a> (Kitano &amp; Tadokoro,
2001), with agent-based simulation used to <em>plan</em> resource allocation for major incidents
(<a href="https://doi.org/10.1016/j.engappai.2015.06.023">Hawe et al., 2015</a>).</p>

<p>So a concrete future iteration of the app: a <strong>mechanism-design dispatch layer</strong>. Picture an incident
commander facing several simultaneous incidents competing for the same scarce units. Today that
allocation is often made under load, ad hoc. A decision-support layer could run the <em>same auction +
doctrine</em> Aftershock uses — a transparent priority mechanism over real incident demand — and, crucially,
<strong>report the price of anarchy of the status-quo allocation versus the coordinated one</strong>: “this dispatch
pattern is leaving an estimated N% of saveable response-time on the table.” That’s the honest framing the
whole project is built on — <em>real demand and latency, simulated outcomes</em> — extended into a what-if tool.
Not a replacement for human incident command (the literature, and common sense, say the human doctrine is
the point); a ruler the commander can hold up against their own decisions.</p>

<p>The other half is the agents. Generative-agent societies (<a href="https://arxiv.org/abs/2304.03442">Park et al., 2023</a>),
multi-agent debate (<a href="https://arxiv.org/abs/2305.14325">Du et al., 2023</a>), and LLM negotiation under
mixed incentives (<a href="https://arxiv.org/abs/2309.17234">Abdelnabi et al., 2023</a>) are all converging on the
same question Aftershock asks in miniature — and the open problems in getting them to cooperate reliably
are exactly the ones <a href="https://arxiv.org/abs/2012.08630">Dafoe et al. (2020)</a> laid out for <em>Cooperative AI</em>.
A dispatch layer is a high-stakes, legible place to study them: the externalities are real, the doctrine
is real, and the price of anarchy is measurable.</p>

<h2 id="the-honest-takeaway">The honest takeaway</h2>

<p>Coordination has a value, and now we can put a number on it: on this benchmark the protocol-free swarm
pays a ~1.11× price of anarchy (pooled over fifteen seeds; ~1.16× on the five-seed four-arm
cross-section), and — the cleaner result — <em>coordinated</em> play (whether a hand-tuned heuristic or an LLM
society) beats <em>uncoordinated</em> play (whether a swarm or one big model) by ~8 points of saveable lives. The society-vs-swarm edge itself remains suggestive, p=0.118; the order flips on the
hardest real scenario; and the agents aren’t really solving for equilibrium at all. The interesting work
isn’t claiming a bigger win — it’s making the coordination <em>self-enforcing</em>, measuring it against a
<em>tight</em> optimum, and pointing the same ruler at a real dispatch board.</p>

<p>Build the ruler first, as ever. Then let it tell you what to build.</p>

<p>Live demo: <strong><a href="https://aftershock.redoubtlabs.dev">https://aftershock.redoubtlabs.dev</a></strong> · Code: <strong><a href="https://github.com/bluntmachetti/aftershock">https://github.com/bluntmachetti/aftershock</a></strong>
(method + verdict in <code class="language-plaintext highlighter-rouge">docs/EVIDENCE.md</code> §3 and <code class="language-plaintext highlighter-rouge">docs/FIELD-NOTES.md</code> §25)</p>

<hr />

<h3 id="related-work">Related work</h3>

<p><em>Every reference below was independently checked before publishing (Log 006’s lesson). Foundations of
game theory and mechanism design; recent multi-agent-LLM work; and the incident-response literature the
application section draws on.</em></p>

<p><strong>Price of anarchy &amp; efficiency of equilibria</strong></p>
<ul>
  <li>Koutsoupias, E. &amp; Papadimitriou, C. (1999). <em>Worst-Case Equilibria.</em> STACS ‘99, LNCS 1563, 404–413. <a href="https://doi.org/10.1007/3-540-49116-3_38">https://doi.org/10.1007/3-540-49116-3_38</a></li>
  <li>Papadimitriou, C. H. (2001). <em>Algorithms, Games, and the Internet.</em> STOC ‘01, 749–753. <a href="https://doi.org/10.1145/380752.380883">https://doi.org/10.1145/380752.380883</a></li>
  <li>Roughgarden, T. &amp; Tardos, É. (2002). <em>How Bad Is Selfish Routing?</em> Journal of the ACM, 49(2), 236–259. <a href="https://doi.org/10.1145/506147.506153">https://doi.org/10.1145/506147.506153</a></li>
  <li>Roughgarden, T. (2015). <em>Intrinsic Robustness of the Price of Anarchy.</em> Journal of the ACM, 62(5). <a href="https://theory.stanford.edu/~tim/papers/robust.pdf">https://theory.stanford.edu/~tim/papers/robust.pdf</a></li>
  <li>Nisan, N., Roughgarden, T., Tardos, É. &amp; Vazirani, V. (eds.) (2007). <em>Algorithmic Game Theory.</em> Cambridge University Press. <a href="https://doi.org/10.1017/CBO9780511800481">https://doi.org/10.1017/CBO9780511800481</a></li>
</ul>

<p><strong>Congestion games &amp; the commons</strong></p>
<ul>
  <li>Rosenthal, R. W. (1973). <em>A class of games possessing pure-strategy Nash equilibria.</em> International Journal of Game Theory, 2, 65–67. <a href="https://doi.org/10.1007/BF01737559">https://doi.org/10.1007/BF01737559</a></li>
  <li>Hardin, G. (1968). <em>The Tragedy of the Commons.</em> Science, 162(3859), 1243–1248. <a href="https://doi.org/10.1126/science.162.3859.1243">https://doi.org/10.1126/science.162.3859.1243</a></li>
  <li>Ostrom, E. (1990). <em>Governing the Commons.</em> Cambridge University Press. <a href="https://doi.org/10.1017/CBO9780511807763">https://doi.org/10.1017/CBO9780511807763</a></li>
</ul>

<p><strong>Mechanism design &amp; correlated equilibrium</strong></p>
<ul>
  <li>Vickrey, W. (1961). <em>Counterspeculation, Auctions, and Competitive Sealed Tenders.</em> Journal of Finance, 16(1), 8–37. <a href="https://doi.org/10.1111/j.1540-6261.1961.tb02789.x">https://doi.org/10.1111/j.1540-6261.1961.tb02789.x</a></li>
  <li>Clarke, E. H. (1971). <em>Multipart Pricing of Public Goods.</em> Public Choice, 11, 17–33. <a href="https://doi.org/10.1007/BF01726210">https://doi.org/10.1007/BF01726210</a></li>
  <li>Groves, T. (1973). <em>Incentives in Teams.</em> Econometrica, 41(4), 617–631. <a href="https://www.jstor.org/stable/1914085">https://www.jstor.org/stable/1914085</a></li>
  <li>Aumann, R. J. (1974). <em>Subjectivity and Correlation in Randomized Strategies.</em> Journal of Mathematical Economics, 1(1), 67–96. <a href="https://doi.org/10.1016/0304-4068(74)90037-8">https://doi.org/10.1016/0304-4068(74)90037-8</a></li>
</ul>

<p><strong>Multi-agent LLM systems</strong></p>
<ul>
  <li>Park, J. S., et al. (2023). <em>Generative Agents: Interactive Simulacra of Human Behavior.</em> UIST ‘23; arXiv:2304.03442. <a href="https://arxiv.org/abs/2304.03442">https://arxiv.org/abs/2304.03442</a></li>
  <li>Du, Y., et al. (2023). <em>Improving Factuality and Reasoning in Language Models through Multiagent Debate.</em> arXiv:2305.14325. <a href="https://arxiv.org/abs/2305.14325">https://arxiv.org/abs/2305.14325</a></li>
  <li>Abdelnabi, S., et al. (2023). <em>Cooperation, Competition, and Maliciousness: LLM-Stakeholders Interactive Negotiation.</em> arXiv:2309.17234. <a href="https://arxiv.org/abs/2309.17234">https://arxiv.org/abs/2309.17234</a></li>
  <li>Cemri, M., et al. (2025). <em>Why Do Multi-Agent LLM Systems Fail?</em> arXiv:2503.13657. <a href="https://arxiv.org/abs/2503.13657">https://arxiv.org/abs/2503.13657</a></li>
  <li>Dafoe, A., et al. (2020). <em>Open Problems in Cooperative AI.</em> arXiv:2012.08630. <a href="https://arxiv.org/abs/2012.08630">https://arxiv.org/abs/2012.08630</a></li>
</ul>

<p><strong>Incident response &amp; emergency resource allocation</strong></p>
<ul>
  <li>FEMA (2017). <em>National Incident Management System,</em> 3rd ed. U.S. Dept. of Homeland Security. <a href="https://www.fema.gov/sites/default/files/2020-07/fema_nims_doctrine-2017.pdf">https://www.fema.gov/sites/default/files/2020-07/fema_nims_doctrine-2017.pdf</a></li>
  <li>Kitano, H. &amp; Tadokoro, S. (2001). <em>RoboCup Rescue: A Grand Challenge for Multiagent and Intelligent Systems.</em> AI Magazine, 22(1), 39–52. <a href="https://doi.org/10.1609/aimag.v22i1.1542">https://doi.org/10.1609/aimag.v22i1.1542</a></li>
  <li>Mukhopadhyay, A., et al. (2022). <em>A Review of Incident Prediction, Resource Allocation, and Dispatch Models for Emergency Management.</em> Accident Analysis &amp; Prevention, 165, 106501; arXiv:2006.04200. <a href="https://arxiv.org/abs/2006.04200">https://arxiv.org/abs/2006.04200</a></li>
  <li>Tassone, J. &amp; Choudhury, S. (2020). <em>A Comprehensive Survey on the Ambulance Routing and Location Problems.</em> arXiv:2001.05288. <a href="https://arxiv.org/abs/2001.05288">https://arxiv.org/abs/2001.05288</a></li>
  <li>Hawe, G. I., et al. (2015). <em>Agent-based simulation of emergency response to plan the allocation of resources for a hypothetical two-site major incident.</em> Engineering Applications of Artificial Intelligence, 46, 336–345. <a href="https://doi.org/10.1016/j.engappai.2015.06.023">https://doi.org/10.1016/j.engappai.2015.06.023</a></li>
</ul>]]></content><author><name>Kenny Ademolu</name></author><summary type="html"><![CDATA[Someone asked whether 'society beats swarm' is really a Nash-equilibrium story. It is — Aftershock is a common-pool resource game, the swarm is the uncoordinated price-of-anarchy baseline, and the society's auction + doctrine is a coordination mechanism. So I built a ruler for it. Measured as the fraction of imperiled lives saved, both coordinated arms (society 67.3%, the scripted central heuristic 66.2%) sit ~8 points above both uncoordinated ones (solo 58.9%, swarm 58.1%) — and the expensive single big model lands at the swarm's anarchy level. The society-vs-swarm gap itself stays suggestive (+6.7 pts, p=0.118). A field report on the game theory under the sim, what we can't yet claim, the experiments that would firm it, and how a mechanism-design dispatch layer could apply to real incident response — with the related work, checked.]]></summary></entry><entry><title type="html">We firmed our headline until it broke. Here’s the one that didn’t.</title><link href="https://aftershock.redoubtlabs.dev/2026/06/25/the-headline-that-survives.html" rel="alternate" type="text/html" title="We firmed our headline until it broke. Here’s the one that didn’t." /><published>2026-06-25T16:00:00+00:00</published><updated>2026-06-25T16:00:00+00:00</updated><id>https://aftershock.redoubtlabs.dev/2026/06/25/the-headline-that-survives</id><content type="html" xml:base="https://aftershock.redoubtlabs.dev/2026/06/25/the-headline-that-survives.html"><![CDATA[<p>Three logs back I put a caveat on our own flagship number, and <a href="/aftershock/2026/06/22/the-protocol-was-worth-28-lives-now-its-worth-a-caveat.html">last log I firmed it and watched
it collapse</a>.
The claim that had been on Aftershock’s front page since Log 001 — that a <em>coordinated</em> society of
small Qwen models saves <strong>+28 more lives</strong> than the same five models with no protocol — was an n=5
mean leaning on one lucky seed. Re-run from five paired seeds to fifteen, it came out <strong>+8.9 lives</strong>:
directionally right (the society won 11 of 15 seeds; the bootstrap 95% CI <strong>[+2.3, +15.4]</strong> excludes
zero) but a two-sided sign-test <strong>p = 0.118</strong> that doesn’t clear significance.</p>

<p>Honest. Also soft. A judge who knows statistics will read “+8.9, p = 0.118” and — correctly —
discount it. Which forced the question I’d been able to dodge while the lives number still looked
big: <strong>if your proudest result is only suggestive, what do you actually put on the front page?</strong></p>

<p>The rule we landed on is the one that’s run through this whole project: <strong>lead with what survives
scrutiny.</strong> Not the flashiest number — the one that’s still true after a skeptic checks it. Two of
ours are. So I rewrote the README, the evidence pack, the submission, and the blog’s own headline
around them.</p>

<h2 id="what-survives-1--written-doctrine-lifts-conformance-credibly">What survives, #1 — written doctrine lifts conformance, <em>credibly</em></h2>

<p>Aftershock scores every agent against a two-tier playbook (a role envelope + a decision registry):
how often does each role actually follow the protocol it’s given? That rate is <code class="language-plaintext highlighter-rouge">team_alignment</code>.
The causal test is a paired ablation — same world seeds, same tools, the doctrine layer toggled
<strong>off vs on</strong> — and it’s the cleanest result in the project:</p>

<div class="readout-table">
  <div class="rt-cap"><span class="sq"></span>Doctrine off → on (paired ablation, conformance)</div>
  <table class="rt">
    <thead>
      <tr><th>Batch</th><th>team_alignment Δ</th><th>Seeds positive</th><th>Sign test</th><th>Verdict</th></tr>
    </thead>
    <tbody>
      <tr class="lose"><td>2026-06-16 · n = 5</td><td><strong>+0.156</strong></td><td>5 / 5</td><td>p = 0.0625</td><td>suggestive</td></tr>
      <tr class="win"><td><strong>2026-06-22 · n = 6 (re-test)</strong></td><td><strong>+0.125</strong></td><td>6 / 6</td><td><strong>p = 0.03125</strong></td><td><strong>credible</strong></td></tr>
    </tbody>
  </table>
</div>

<p>The effect is positive on <strong>all 11 seeds across both runs</strong>, and at n=6 it finally clears the
sign-test floor (five-for-five is only p=0.0625 — as strong as five coin flips get; the sixth seed
tips it to p=0.03125). Crucially, doctrine buys this alignment at <strong>no lives cost</strong> — the lives
delta in the same ablation is noise (p=0.375) in both runs. The structure makes the agents <em>follow
the protocol</em>, not save more people; we don’t conflate the two.</p>

<p>And on the run a judge actually lands on — <code class="language-plaintext highlighter-rouge">seed91-society</code>, 65 ticks on <strong>real NYC Hurricane Ida</strong>
dispatch demand — the society follows its doctrine <strong>95.2%</strong> of the time (<code class="language-plaintext highlighter-rouge">team_alignment = 0.9517</code>).
That’s the number I’d defend in a room full of Qwen engineers: structured instruction-following,
measured deterministically, reproducible from the committed conformance file.</p>

<blockquote>
  <p><strong>Conformance ≠ outcome.</strong> 95% alignment means the agents obeyed the protocol — it does <em>not</em> mean
they rescued everyone. Outcomes (lives saved/lost) are a fully simulated model; we never claim the
agents beat real outcomes. The conformance number proves instruction-following, full stop.</p>
</blockquote>

<h2 id="what-survives-2--the-cost-efficiency-is-real">What survives, #2 — the cost-efficiency is real</h2>

<p>The other claim a skeptic can’t knock down is about money. On the 4-arm benchmark (paired seeds, 60
ticks), six cheap <code class="language-plaintext highlighter-rouge">qwen3.5-flash</code> workers plus one <code class="language-plaintext highlighter-rouge">qwen3.5-plus</code> commander:</p>

<div class="readout-table">
  <div class="rt-cap"><span class="sq"></span>4-arm benchmark — lives, cost, and lives-per-dollar</div>
  <table class="rt">
    <thead>
      <tr><th>Arm</th><th>Mean lives</th><th>Cost / run</th><th>Lives per $</th></tr>
    </thead>
    <tbody>
      <tr><td>scripted (expert heuristics, $0)</td><td>106.8</td><td>$0.0000</td><td>— (free control)</td></tr>
      <tr class="win"><td><strong>society</strong> (6-role, negotiation)</td><td><strong>108.4</strong></td><td><strong>$0.0353</strong></td><td><strong>3,069</strong></td></tr>
      <tr class="lose"><td>solo (one big model)</td><td>95.6</td><td>$0.0515</td><td>1,855</td></tr>
    </tbody>
  </table>
</div>

<p>The society <strong>matches hand-tuned expert heuristics on lives</strong> (108.4 vs 106.8 — a coordinated team
of small models holding its own against domain expertise) and <strong>out-delivers the single big model</strong>
(108.4 vs 95.6) at <strong>31% lower cost</strong> — which is <strong>~65% better lives-per-dollar</strong> (3,069 vs 1,855).
That’s the Qwen-track thesis stated in a way that doesn’t depend on a fragile p-value: cheap models,
coordinated by a protocol, beat one expensive model for less money. (A later contract trim — Log 005
— cut another ~14% off the society’s per-run cost without touching conformance, on top of this.)</p>

<h2 id="what-were-not-leading-with-anymore">What we’re <em>not</em> leading with anymore</h2>

<p>The +8.9-lives society-vs-swarm edge doesn’t get deleted — that would be its own kind of dishonesty.
It’s directionally consistent (society wins 11/15), its CI excludes zero, and it’s the honest residue
of the number we used to headline. It stays in the evidence pack, <strong>labeled suggestive</strong>:</p>

<div class="readout-table">
  <div class="rt-cap"><span class="sq"></span>Society vs swarm — kept, but demoted to suggestive</div>
  <table class="rt">
    <thead>
      <tr><th>Stat</th><th>Value</th></tr>
    </thead>
    <tbody>
      <tr><td>Mean Δ lives (society − swarm), n = 15</td><td><strong>+8.9</strong></td></tr>
      <tr><td>Seeds society won</td><td>11 / 15</td></tr>
      <tr><td>Bootstrap 95% CI</td><td>[+2.3, +15.4] (excludes 0)</td></tr>
      <tr class="lose"><td>Sign-test p</td><td>0.118 — <strong>suggestive, not significant</strong></td></tr>
    </tbody>
  </table>
</div>

<p>By the harness’s own three-tier rule (credible = CI-excludes-0 <strong>and</strong> sign-significant; suggestive =
exactly one; noise = neither), exactly one condition holds — so it’s suggestive, and that’s what we
write. The point of the rule is that it demotes <em>us</em>, not just other people’s claims.</p>

<h2 id="the-evidence-is-finally-visible-on-landing">The evidence is finally visible on landing</h2>

<p>There’s a postscript that belongs in a build log. While reframing the writing, I checked what a judge
actually sees at <a href="https://aftershock.redoubtlabs.dev">https://aftershock.redoubtlabs.dev</a> — and it was greeting visitors with <strong>“No runs
found”</strong> everywhere and a Bench tab stuck on “Loading…” forever. All that carefully-firmed evidence
was invisible on first contact.</p>

<p>The cause was almost funny: the public demo runs a back-to-back ambient simulation to keep the Live
tab alive, and over thirteen days it had quietly written <strong>32,709 throwaway run directories</strong>. The
run-list endpoint read <em>every</em> one on <em>every</em> request; at 32k it took <strong>62 seconds</strong> to answer and
blocked the bench endpoint behind it. The fix was three parts — prune the firehose and cap it so it
self-heals, list every curated run but only the newest handful of ambient ones, and <strong>bundle the
demo arc into the repo itself</strong> so a fresh clone or a fresh box shows real data immediately instead of
an empty panel. <code class="language-plaintext highlighter-rouge">/api/runs</code> went from 62s to under a second; the observatory now loads <code class="language-plaintext highlighter-rouge">seed91-society</code>
— that 95%-conformance NYC-Ida run — on landing, no clicks.</p>

<p>It’s the same lesson as Log 006, wearing yet another hat: <em>a system that intends to show its evidence
isn’t showing it until you look at what a stranger actually sees.</em> The blog could describe our
credibility all it wanted; the app needed to put it on screen.</p>

<h2 id="the-honest-headline">The honest headline</h2>

<p>“Society achieves 0.95 doctrine conformance — credible at p=0.031 — at ~65% better lives-per-dollar
than one big model” is less of a flex than “+28 lives saved.” It’s also the version that’s still true
after you check it. Every figure here traces to a file in the repo
(<a href="https://github.com/bluntmachetti/aftershock/blob/main/docs/EVIDENCE.md">docs/EVIDENCE.md</a>), and the
field log keeps the receipts — including the ghost we chased and the headline we had to walk back. If
there’s one thing this project is for, it’s that: pick the claim that survives scrutiny, and let the
ruler demote you when it should.</p>

<p>Live demo: <strong><a href="https://aftershock.redoubtlabs.dev">https://aftershock.redoubtlabs.dev</a></strong> · Code: <strong><a href="https://github.com/bluntmachetti/aftershock">https://github.com/bluntmachetti/aftershock</a></strong></p>]]></content><author><name>Kenny Ademolu</name></author><summary type="html"><![CDATA[Last log, our flagship claim — a coordinated Qwen society saves '+28 more lives' than an uncoordinated swarm — firmed from five seeds to fifteen and collapsed to a suggestive +8.9 (sign-test p=0.118). Honest, but soft: a judge who knows statistics will discount it. So which claim do you put on the front page when your proudest number is only suggestive? The rule we settled on — lead with what survives scrutiny — and the two results of ours that do: doctrine conformance credible at p=0.031, and ~65% better lives-per-dollar than one big model. Plus the demo fix that finally made the observatory show that evidence on first contact.]]></summary></entry><entry><title type="html">The protocol was ‘worth 28 lives.’ At fifteen seeds it’s worth a caveat.</title><link href="https://aftershock.redoubtlabs.dev/2026/06/22/the-protocol-was-worth-28-lives-now-its-worth-a-caveat.html" rel="alternate" type="text/html" title="The protocol was ‘worth 28 lives.’ At fifteen seeds it’s worth a caveat." /><published>2026-06-22T19:00:00+00:00</published><updated>2026-06-22T19:00:00+00:00</updated><id>https://aftershock.redoubtlabs.dev/2026/06/22/the-protocol-was-worth-28-lives-now-its-worth-a-caveat</id><content type="html" xml:base="https://aftershock.redoubtlabs.dev/2026/06/22/the-protocol-was-worth-28-lives-now-its-worth-a-caveat.html"><![CDATA[<p>Three logs ago I <a href="/aftershock/2026/06/15/build-the-ruler-first.html">put a caveat on our own flagship number</a>
and made a promise. The claim that’s been on <a href="https://github.com/bluntmachetti/aftershock"><strong>Aftershock</strong></a>’s
front page since Log 001 — that a <em>coordinated</em> society of small Qwen models saves <strong>+28 more lives</strong> than the
same five models with no protocol — was an n=5 paired mean leaning hard on a single lucky seed. I wrote, in
plain text: <em>the headline figure is an n=5 mean with a wide interval; to put a tight bound on the number you’d
want ~25 seeds.</em> I said I’d firm it.</p>

<p>My Alibaba Cloud hackathon credits landed this week. The obvious move was to spend them on new experiments. I
spent the first of them keeping that promise instead — and the number didn’t survive.</p>

<h2 id="build-the-audit-trail-before-you-generate-the-data">Build the audit trail before you generate the data</h2>

<p>I had credits and a backlog. The temptation is to start running. But I’d already learned (Log 004, Log 006)
that the expensive mistakes in this project aren’t bad runs — they’re <em>believing</em> runs I shouldn’t. So before
spending a token, I built the thing that makes belief cheap and honest: an experiment tracker.</p>

<p>Not a big one. A sibling project of mine has a proper one — a database, schema-pinned ledgers, a hash-chained
research log, viability certificates. I read all of it and then deliberately <em>didn’t</em> port it. Aftershock is a
two-week hackathon repo with one model family; that machinery is paper-grade over-build here. What it actually
lacked was small and specific: none of the ~dozen result folders carried the commit they were run on, the
JSON had quietly drifted across versions, and there was no way to ask “which of my experiments are <em>credible</em>?”
across the whole set.</p>

<p>So the tracker is three thin things: a <strong>provenance stamp</strong> on every result file (schema version, git SHA,
which endpoint — cloud DashScope vs a local model — and a digest of the deterministic scripted baseline so a
silent regression in the control is detectable); a <strong>one-file index</strong> built by a read-only script that walks
every run and emits one queryable row each; and a link from a result to the field note it backs. About 350
lines, pure standard library, no new dependencies. The point of building it <em>first</em> is the same as building a
ruler before you cut: you want the measurement in place before the thing you’re measuring exists.</p>

<h2 id="the-tools-first-job-was-catching-itself">The tool’s first job was catching itself</h2>

<p>The first real experiment I pointed it at was a cheap, important one. An earlier finding (Log 002 territory)
showed that <em>written doctrine</em> — a two-tier playbook the agents are scored against — raises how often the
society follows its own protocol. At five seeds that effect was real on every seed but sat just shy of
significance (a sign-test floor of p=0.0625, because five-for-five is as strong as five coin flips get). One
more seed would tip it. So I ran a sixth.</p>

<p>The conformance lifted, six-for-six positive, sign test now p=0.031 — <strong>credible</strong>. I went to read it back out
of the new index, and the index said the experiment’s verdict was: <strong>noise.</strong></p>

<p>It wasn’t wrong about a number. It was reading the <em>wrong</em> number. The tracker computed its one headline
verdict from the <em>lives</em> delta — which for a doctrine change is pure noise, by design, because doctrine buys
<em>conformance</em>, not lives. The credible result was sitting right there in the data and the tool I’d built to
keep me honest was filing it under “nothing to see.” The honesty layer was mislabeling on day one.</p>

<p>That’s the recurring lesson of this whole project wearing a new hat: a dashboard that intends to be honest
isn’t honest until you audit what it actually surfaces. I taught the tracker to compute a <strong>separate
conformance verdict</strong> with the same statistics, and <em>then</em> the doctrine result read credible. The fix paid
off twice in one afternoon — because the very next experiment was the one I’d been avoiding.</p>

<h2 id="the-headline-firmed-28--a-question-mark">The headline, firmed: +28 → a question mark</h2>

<p>The promise from Log 004 was ~25 seeds. I went and got them. The society-vs-swarm contrast, re-run on the
<em>current</em> code, across three batches, pooled into one paired test:</p>

<div class="readout-table">
  <div class="rt-cap"><span class="sq"></span>Society vs swarm — the "+28" firmed from five seeds to fifteen</div>
  <table class="rt">
    <thead>
      <tr><th>Batch</th><th>Δ lives</th><th>Society wins</th><th>Sign test / CI</th></tr>
    </thead>
    <tbody>
      <tr class="lose"><td>2026-06-11 · n = 5 (the published number)</td><td><strong>+27.6</strong></td><td>4 / 5</td><td>p = 0.125</td></tr>
      <tr class="lose"><td>2026-06-22 · same 5 seeds, current code</td><td><strong>+14.6</strong></td><td>4 / 5</td><td>—</td></tr>
      <tr class="lose"><td>2026-06-22 · 10 fresh seeds</td><td><strong>+6.0</strong></td><td>7 / 10</td><td>—</td></tr>
      <tr class="win"><td><strong>pooled · n = 15</strong></td><td><strong>+8.9</strong></td><td>11 / 15</td><td>p = 0.118 · CI [+2.3, +15.4] <em>excludes 0</em></td></tr>
    </tbody>
  </table>
</div>

<p>Read top to bottom, that’s a number deflating in real time. The same five seeds that gave +27.6 in June gave
+14.6 on today’s code. Ten brand-new seeds came back at +6.0. Pool all fifteen and you get <strong>+8.9 lives, with
a confidence interval [+2.3, +15.4] that just clears zero but a sign test (p=0.118) that doesn’t clear
significance.</strong> The tracker calls that <em>suggestive</em> — exactly one of its two bars met, not both.</p>

<p>The culprit is the one Log 004 already named: a single seed. In the original five, seed 11 was a +88-life
blowout that dragged the mean up; the other four averaged about +12. Once the sample is big enough that no one
lucky draw can carry it, the magnitude regresses to a small, not-significant edge. The <em>direction</em> still holds
— the society wins 11 of 15 seeds, it does beat the uncoordinated swarm more often than not — but the <strong>number</strong>
on the homepage does not survive being firmed.</p>

<p>So I did the unglamorous thing. I rewrote the README, the submission writeup, and the judge-facing evidence
pack to lead with what’s true: society-vs-swarm is <em>suggestive, not statistically significant (+8.9 at n=15,
CI [+2.3, +15.4] excludes 0 but the sign test p=0.118 doesn’t clear significance)</em>, and the earlier +28 was a
small-sample overestimate. The blog posts that reported +28 at the
time stay exactly as they were — they were honest about what we knew <em>then</em>, and rewriting history would be
its own dishonesty. This is the next chapter, not a retcon.</p>

<h2 id="and-the-cost-trim-kept-honest">And the cost trim, kept honest</h2>

<p>While the tracker was on, I closed one more open question. A while back I trimmed the static prompt every agent
re-sends each tick and cut run cost ~14% in a clean A/B ($0.0411→$0.0353, Log 005) — about ~16% cumulatively
since the 2026-06-11 launch ($0.0423→$0.0353), a different baseline. I’d flagged a small conformance dip from
that trim as a
“watch-item — could be noise.” Now that conformance is the part of the story that <em>survived</em>, I owed it a real
answer, so I built a clean A/B toggle and ran it at ten seeds.</p>

<p>The dip is <strong>real but tiny: −0.019 team-alignment</strong>, with a confidence interval that just clears zero but a
sign test that doesn’t (the tracker calls it <em>suggestive</em>) — and <strong>zero</strong> lives cost. So the −14% cost cut is
<em>nearly</em> free, not perfectly free. Worth knowing, not worth reversing. The point is that I now know which it
is, instead of guessing.</p>

<h2 id="what-survives">What survives</h2>

<p>Here’s the honest scoreboard after a session spent measuring instead of adding:</p>

<ul>
  <li><strong>Cost-efficiency — robust.</strong> Six <code class="language-plaintext highlighter-rouge">qwen3.5-flash</code> workers under a <code class="language-plaintext highlighter-rouge">qwen3.5-plus</code> commander match well-tuned
expert heuristics (108 vs 107 lives) and a single big model (108 vs 96 for solo <code class="language-plaintext highlighter-rouge">qwen3-max</code>) at <strong>~$0.035 a
run</strong> — over 50% better lives-per-dollar than the big model. That’s the claim I’d stake the submission on.</li>
  <li><strong>Conformance — now credible.</strong> Written doctrine lifts protocol-following by a verdict that finally clears
significance (p=0.031, six-for-six).</li>
  <li><strong>Society vs swarm on lives — a question mark.</strong> Suggestive (11/15, CI [+2.3, +15.4] excludes 0) but not
significant (sign test p=0.118). The marquee magnitude was the weakest claim, and it’s the one that didn’t
hold.</li>
</ul>

<p>Losing your headline number is supposed to feel bad. It mostly feels like relief, because the alternative was a
judge running <code class="language-plaintext highlighter-rouge">aftershock bench</code> and finding +9 where the slide said +28. The tracker earned its entire
existence in one session by demoting me, on purpose, before anyone else could.</p>

<p>If there’s a takeaway sharper than Log 004’s “build the ruler first,” it’s this: <strong>firm your <em>proudest</em> number
first.</strong> The figure you most want to be true is the one most likely to be a small-sample flatter, and it’s the
one with the most riding on being wrong. Point the audit trail at it on day one. The best day a measurement
tool has is the day it tells you the thing you were about to brag about isn’t there.</p>

<p><strong>Try it live:</strong> <a href="https://aftershock.redoubtlabs.dev">https://aftershock.redoubtlabs.dev</a> · <strong>Read the code:</strong> <a href="https://github.com/bluntmachetti/aftershock">https://github.com/bluntmachetti/aftershock</a>
(the firming lives in <code class="language-plaintext highlighter-rouge">aftershock ablation</code>; every number above traces to a file in the
<a href="https://github.com/bluntmachetti/aftershock/blob/main/docs/EVIDENCE.md">judge evidence pack</a>)</p>

<p><em>Built with Qwen Cloud (<code class="language-plaintext highlighter-rouge">qwen3.5-flash</code> / <code class="language-plaintext highlighter-rouge">qwen3.5-plus</code> / <code class="language-plaintext highlighter-rouge">qwen3-max</code> via DashScope) and Alibaba Cloud ECS,
for the Qwen Cloud Global AI Hackathon.</em></p>]]></content><author><name>Kenny Ademolu</name></author><summary type="html"><![CDATA[Three logs ago I caveated Aftershock's flagship claim — that a coordinated Qwen agent society saves ~28 more lives than an uncoordinated swarm — as an n=5 mean leaning on one lucky seed, and promised to firm it. My Alibaba Cloud credits arrived; before spending them on new experiments I built a thin experiment tracker and used it to keep that promise. Firming the +28 to fifteen paired seeds collapsed it to a suggestive +8.9 lives — the CI excludes 0 but the sign test doesn't clear significance. A field report on building the audit trail before you generate the data, watching the tool catch a flaw in itself, and publishing the honest number when your headline doesn't survive.]]></summary></entry><entry><title type="html">We built a proof pack so judges could check our numbers. Auditing it ourselves found a wrong p-value, a fabricated source, and a cherry-picked run.</title><link href="https://aftershock.redoubtlabs.dev/2026/06/19/we-proof-checked-our-proof-pack.html" rel="alternate" type="text/html" title="We built a proof pack so judges could check our numbers. Auditing it ourselves found a wrong p-value, a fabricated source, and a cherry-picked run." /><published>2026-06-19T23:00:00+00:00</published><updated>2026-06-19T23:00:00+00:00</updated><id>https://aftershock.redoubtlabs.dev/2026/06/19/we-proof-checked-our-proof-pack</id><content type="html" xml:base="https://aftershock.redoubtlabs.dev/2026/06/19/we-proof-checked-our-proof-pack.html"><![CDATA[<p>In the <a href="/aftershock/2026/06/16/the-fix-that-would-have-only-fooled-the-scoreboard.html">last post</a>
the lesson was <em>prove the metric does something before you optimize it.</em> This one is the same
discipline pointed somewhere more uncomfortable: at the artifact I built <strong>to be honest.</strong></p>

<p>With the hackathon deadline close, the temptation was to bolt on a flashy feature. The measurement
from the earlier logs said otherwise. <a href="https://github.com/bluntmachetti/aftershock"><strong>Aftershock</strong></a>
was already feature-complete; what it lacked wasn’t capability, it was <strong>legibility</strong> — a judge
couldn’t quickly check that the numbers were real. So the final push wasn’t features. It was <em>proof</em>:
a <strong>Decision Receipt</strong> that chains any contested ruling (kernel decision → the agent’s own stated
rationale → cost → recorded outcome), confidence intervals and a sign test on the benchmark, and the
capstone — a one-page <strong>Evidence Pack</strong> whose entire promise is: <em>every number here traces to a file
in the repo. Go check.</em></p>

<p>It’s the judge’s dream fact-check target. So before I shipped it, I did the judge’s job. I ran a
multi-agent adversarial pass that re-derived <strong>every figure</strong> in the pack from its source — the
<code class="language-plaintext highlighter-rouge">results.json</code>, the run manifests, the scenario JSON — and asked one question per number: <em>does this
actually trace?</em></p>

<p>The honest headline: <strong>42 of 47 figures matched exactly.</strong> The mean lives (society 103.2, swarm
75.6), the costs, the lives-per-dollar, the NYC-Ida demand and latency baseline (948s, 16.5% held) —
all clean. But the five that <em>didn’t</em> trace are the whole point of this post, because the document
that failed them was the one I wrote specifically so it couldn’t.</p>

<h2 id="the-artifact-that-dares-you-to-check-it">The artifact that dares you to check it</h2>

<p>The Evidence Pack opens with a line I was proud of: <em>“Every number below traces to a file in this
repo — no figure is asserted without a source path.”</em> Each claim sits next to its source: a results
file, a <code class="language-plaintext highlighter-rouge">run.json</code> field, a path inside <code class="language-plaintext highlighter-rouge">scenario.json</code>. That framing is a commitment. It also means
a single wrong source citation doesn’t just look sloppy — it detonates the whole document, because a
judge who runs <code class="language-plaintext highlighter-rouge">jq</code> on the cited field and gets back <code class="language-plaintext highlighter-rouge">null</code> will stop trusting <em>every other number on
the page.</em></p>

<p>So that’s exactly what the audit checked: not “is the value plausible,” but “if a skeptic runs the
command next to this number, do they get this number back?”</p>

<h2 id="so-i-checked-it--and-three-citations-lied">So I checked it — and three citations lied</h2>

<div class="readout-table">
  <div class="rt-cap"><span class="sq"></span>Evidence Pack — what it claimed vs what the source said</div>
  <table class="rt">
    <thead>
      <tr><th>Claim</th><th>The pack cited</th><th>The source actually says</th></tr>
    </thead>
    <tbody>
      <tr class="lose"><td>swarm vs scripted — significance</td><td>p = 0.375</td><td><strong>p = 0.0625</strong> (swarm loses 5/5; 0.375 was the <em>society</em> row, copy-pasted)</td></tr>
      <tr class="lose"><td>NYC-Ida <code>pack_digest</code></td><td>"in <code>scenario.json</code>"</td><td>not a field there — <code>jq .pack_digest</code> → <strong>null</strong> (it's a sha256 computed at load)</td></tr>
      <tr class="lose"><td>the "demand real, outcomes simulated" caveat line</td><td>emitted by the loader</td><td>a constant in <code>web.py</code>, chosen per-pack at serve time</td></tr>
      <tr><td>real incident count path</td><td><code>reference.n_incidents</code></td><td><code>reference.<strong>aggregates</strong>.n_incidents</code> (value 2,212 correct)</td></tr>
    </tbody>
  </table>
</div>

<p>None of these <em>flattered</em> the project — the wrong p-value actually <strong>understated</strong> how cleanly the
swarm loses (0.0625 is the strongest verdict five seeds can give; 0.375 was a number that wandered in
from the adjacent row). The <code class="language-plaintext highlighter-rouge">pack_digest</code> value was even <em>correct</em> — it just pointed at the wrong
place to find it. But that’s the trap with a proof artifact: <em>honest intent plus a wrong pointer reads
exactly like a lie to someone checking.</em> A judge running <code class="language-plaintext highlighter-rouge">jq .pack_digest scenario.json</code>, getting
<code class="language-plaintext highlighter-rouge">null</code>, and concluding the whole pack is hand-waved would be <strong>right to.</strong> Every one of these got a
corrected source — the digest now cites the code that computes it and the <code class="language-plaintext highlighter-rouge">run.json</code> field that
stores it; the p-value reads 0.0625.</p>

<p>A small, sharp aside: the AI reviewers I’d used to pressure-test the plan made the <em>same class</em> of
error. One confidently recommended I “ship the scenario pipeline” — a thing already shipped weeks
earlier (caught by checking the disk). Another quoted a flattering conformance figure of <strong>0.915</strong>;
the real number is <strong>0.759</strong> — it had been unable to read the gitignored file and filled the gap with
something plausible. Models hallucinate sources too. The defense is identical: trace it.</p>

<h2 id="the-one-that-stung-a-flagship-at-95-conformance-that-saved-8-of-90-lives">The one that stung: a flagship at 95% conformance that saved 8 of 90 lives</h2>

<p>The traceability misses were fixable typos. This one was a judgment failure, and it’s the reason the
post exists.</p>

<p>The pack showcased <code class="language-plaintext highlighter-rouge">seed91-society</code> — the society running the real NYC Hurricane Ida scenario — as the
flagship demo, headlined by its <strong>doctrine conformance of 0.95</strong>: “Qwen follows the structured
doctrine 95% of the time over a full scenario.” True number. Real signal. And next to it, the pack
said <strong>nothing</strong> about how the run actually went.</p>

<div class="readout-table">
  <div class="rt-cap"><span class="sq"></span>seed91-society — the flagship, fully stated</div>
  <table class="rt">
    <thead>
      <tr><th>Signal</th><th>Value</th></tr>
    </thead>
    <tbody>
      <tr class="win"><td>doctrine conformance</td><td>0.952 (cited)</td></tr>
      <tr class="lose"><td>lives saved / lost</td><td><strong>8 / 82</strong> (8 of ~90 — <em>not</em> cited)</td></tr>
      <tr class="lose"><td>missions failed</td><td>3 (not cited)</td></tr>
    </tbody>
  </table>
</div>

<p>Conformance measures whether agents <em>follow their playbook.</em> It says nothing about whether they
<em>win.</em> Under Ida’s real overwhelming demand, this run followed doctrine almost perfectly and still
lost 82 of 90 lives. Both facts are true and they don’t conflict — but putting “95% disciplined” in
the spotlight and leaving “saved 8 of 90” off the page <strong>implies success the run never had.</strong> A sharp
judge who opened the <code class="language-plaintext highlighter-rouge">run.json</code> would find 8/82 and, fairly, distrust the rest.</p>

<p>This is the cherry-pick failure mode, and it’s seductive precisely <em>because every individual number is
real.</em> You don’t have to fabricate anything to mislead — you just have to be selective about which
true number gets the headline. The fix wasn’t to bury the run; it was to state it whole: a caveat now
sits directly beside it — <em>“conformance measures instruction-following, not lives; this run scored
0.95 but saved only 8 of 90 under heavy Ida demand.”</em> That sentence makes the pack stronger, not
weaker, because it’s the sentence a skeptic was going to write for me.</p>

<h2 id="it-wasnt-only-the-pack">It wasn’t only the pack</h2>

<p>Once I started auditing, the pattern repeated across <em>every</em> honesty surface I’d built that week:</p>

<ul>
  <li>The <strong>Decision Receipt</strong> labeled the <em>commander’s</em> rulings “decided by kernel.” The commander is an
LLM arbiter, not the deterministic engine — calling its calls “kernel” decisions is exactly the kind
of authority-laundering the receipt exists to <em>prevent.</em></li>
  <li>It showed a ruling as <strong>GRANTED</strong> when the auction had accepted the bid but the kernel then <em>rejected
the dispatch downstream</em> — implying a resource reached a mission it never reached.</li>
  <li>It printed a <strong>town-wide</strong> lives-saved delta inside a card scoped to a <em>single</em> ruling, so opening
the receipt for a <em>declined</em> call could show it next to “+1 saved.”</li>
</ul>

<p>Three honesty bugs in the component whose entire job is honesty. All caught the same way: an
independent pass that didn’t trust the summary and went to the source. All fixed before any of it
reached a judge.</p>

<h2 id="the-takeaway">The takeaway</h2>

<p>Aftershock’s thesis, from Log 001, has been one sentence: <em>don’t trust the summary — check the
receipts.</em> It’s the argument for the whole project: typed decisions over chat transcripts, paired
seeds over a single triumphant run, provenance labels over a confident demo.</p>

<p>This week that argument turned around and pointed at me. I built the most honest artifact I could —
a pack that <em>invites</em> fact-checking — and it still shipped a wrong p-value, a citation to a field that
doesn’t exist, and a flagship that omitted its own outcome. Not from bad faith. From the ordinary
gravity that pulls every summary toward looking better than the thing it summarizes.</p>

<p>The lesson is narrow and, I think, the most useful one of the whole build:</p>

<p><strong>Intending to be honest is not the same as being honest. A proof artifact is itself a claim, and
claims need an adversary.</strong> The Evidence Pack only became trustworthy <em>after</em> something tried to break
it — and the thing that broke it wasn’t more good intentions, it was the same boring discipline as the
ruler in Log 004: re-derive the number from the source, and believe only what survives.</p>

<p>If you build a system to keep agents honest, point it at yourself last. That’s where it finds the most.</p>

<p><strong>Try it live:</strong> <a href="https://aftershock.redoubtlabs.dev">https://aftershock.redoubtlabs.dev</a> · <strong>Read the code:</strong> <a href="https://github.com/bluntmachetti/aftershock">https://github.com/bluntmachetti/aftershock</a>
(the corrected proof bundle is
<a href="https://github.com/bluntmachetti/aftershock/blob/main/docs/EVIDENCE.md"><code class="language-plaintext highlighter-rouge">docs/EVIDENCE.md</code></a>;
the receipt is <code class="language-plaintext highlighter-rouge">web/src/components/DecisionReceipt.tsx</code>)</p>

<p><em>Built with Qwen Cloud (<code class="language-plaintext highlighter-rouge">qwen3.5-flash</code> / <code class="language-plaintext highlighter-rouge">qwen3.5-plus</code> / <code class="language-plaintext highlighter-rouge">qwen3-max</code> via DashScope) and Alibaba
Cloud ECS, for the Qwen Cloud Global AI Hackathon.</em></p>]]></content><author><name>Kenny Ademolu</name></author><summary type="html"><![CDATA[With the deadline close, the right move for Aftershock wasn't more features — it was making the proof legible. So I built a one-page evidence pack where every number traces to a file, the judge's dream fact-check target. Then I fact-checked it. The artifact built specifically to be honest had a wrong p-value, a digest sourced from a field that doesn't exist, and a flagship run quietly cited at 95% conformance while it saved 8 of 90 lives. A field report on the difference between intending to be honest and auditing your honesty.]]></summary></entry><entry><title type="html">The fix that would have only fooled the scoreboard — and the one tuning that actually paid.</title><link href="https://aftershock.redoubtlabs.dev/2026/06/16/the-fix-that-would-have-only-fooled-the-scoreboard.html" rel="alternate" type="text/html" title="The fix that would have only fooled the scoreboard — and the one tuning that actually paid." /><published>2026-06-16T21:00:00+00:00</published><updated>2026-06-16T21:00:00+00:00</updated><id>https://aftershock.redoubtlabs.dev/2026/06/16/the-fix-that-would-have-only-fooled-the-scoreboard</id><content type="html" xml:base="https://aftershock.redoubtlabs.dev/2026/06/16/the-fix-that-would-have-only-fooled-the-scoreboard.html"><![CDATA[<p>In the <a href="/aftershock/2026/06/15/build-the-ruler-first.html">last post</a> I built a <em>ruler</em> for
<a href="https://github.com/bluntmachetti/aftershock"><strong>Aftershock</strong></a> — paired ablations, a sign test, a
power curve — before tuning the Qwen agent society at all. This post is what happened when I finally
used it: a session of four levers, each gated by the ruler.</p>

<p>I expected the ruler to catch <em>noise</em> — a win that’s really a coin flip. It did that. But it also kept
catching something subtler and, honestly, more embarrassing: levers that would <strong>work</strong> — move the
exact number I aimed them at — and <strong>change nothing that matters.</strong> I came within one code edit of
shipping a “fix” whose entire effect would have been to make a metric look better while the system
behaved identically.</p>

<p>This is a post about <em>outcome-neutral</em> metrics, and the discipline of asking, before you optimize a
number, whether the number does anything.</p>

<h2 id="the-setup-the-societys-real-story-is-cost-and-discipline-not-lives">The setup: the society’s real story is cost and discipline, not lives</h2>

<p>A quick recap of where the measurement left me. On Aftershock’s task, <strong>well-tuned scripted bots
match every LLM arm on lives saved</strong> — the negotiation <em>protocol</em>, not model IQ, carries the result.
And under genuine triage there’s <a href="/aftershock/2026/06/15/build-the-ruler-first.html">no detectable lives edge</a>
of the society over an uncoordinated swarm. So the society’s honest, defensible value isn’t <em>more
lives</em> — it’s <strong>cost-efficiency</strong> (small models, coordinated, at a fraction of a big model’s price)
and <strong>conformance</strong> (a deterministic measure of whether agents actually follow their doctrine).</p>

<p>That reframing matters for everything below: it means a “win” on lives is usually noise, and a win
worth shipping is one that moves <strong>cost</strong> or <strong>conformance</strong> — <em>without quietly costing the other.</em></p>

<h2 id="lever-1--does-discipline-cost-lives-an-old-scare-resolved">Lever 1 — does discipline cost lives? (an old scare, resolved)</h2>

<p>Early on I’d given every agent a two-tier playbook — a “doctrine” — and a checker that scores how
well they follow it. Writing the doctrine clearly <em>raised</em> conformance. But a single-seed run had a
worrying side effect: the doctrine run saved <strong>fewer</strong> lives (96 vs 113). Discipline isn’t free —
every instruction you add to a prompt is more to read and obey. I’d left it flagged as <em>outcomes
TBD.</em></p>

<p>n=1 is not a result, so I built a same-arm ablation: run the society <strong>with and without</strong> doctrine on
the same five seeds, and — because conformance is the deterministic, low-variance signal — make the
report <strong>lead with conformance</strong> and treat lives as the noisy secondary.</p>

<div class="readout-table">
  <div class="rt-cap"><span class="sq"></span>Doctrine on vs off — paired, 5 seeds</div>
  <table class="rt">
    <thead>
      <tr><th>Signal</th><th>Off</th><th>On</th><th>Δ</th></tr>
    </thead>
    <tbody>
      <tr class="win"><td>team conformance</td><td>0.696</td><td>0.852</td><td><strong>+0.156</strong> &nbsp;(all 5 seeds)</td></tr>
      <tr><td>lives saved</td><td>100.4</td><td>104.2</td><td>+3.8 &nbsp;(within noise)</td></tr>
    </tbody>
  </table>
</div>

<p>The scare was a small-sample artifact. Doctrine raises conformance on <strong>every</strong> seed, and lives are
flat-to-slightly-<em>up</em> — the n=1 “−17 lives” was noise. Discipline here is not paid for in lives. That
clears doctrine as a real, free conformance lever and tells me where the rest of the session should
aim: at the one role that still won’t follow it.</p>

<h2 id="lever-2--the-agent-that-wont-follow-the-rules-and-the-guard-i-almost-built-to-cheat">Lever 2 — the agent that won’t follow the rules, and the guard I almost built to cheat</h2>

<p>That role is the infrastructure agent. Even with doctrine, it’s the one specialist that stays below
0.70 conformance. The diagnostic showed <em>why</em> — three distinct failures, not one:</p>

<ul>
  <li><strong>Urgency inflation:</strong> it marks every request urgency 9, even low-severity ones with a distant
deadline.</li>
  <li><strong>Resubmitting rejected work:</strong> it re-issues a decision the engine just rejected.</li>
  <li><strong>Impossible repairs:</strong> it calls <code class="language-plaintext highlighter-rouge">repair_road</code> on districts that aren’t blocked, or when there’s no
repair crew free.</li>
</ul>

<p>First I did the obvious thing: rewrote its prompt to tie each rule to the exact fields it already sees
in its observation. That <strong>cleanly fixed urgency</strong> (0.35 → 1.00 conformance on that rule) — a numeric
threshold the model can apply. But the <em>impossible-repairs</em> rule barely moved. Telling the flash model
“only repair a district on the BLOCKED line, and only if crew ≥ 1” just… didn’t take. Precondition
<em>gating</em> is harder to prompt than scalar <em>calibration.</em></p>

<p>So I reached for the backlog idea: a <strong>deterministic guard</strong> — enforce the precondition in code so an
invalid repair can never happen. And then, tracing the code to place it, I stopped.</p>

<p><strong>The engine already rejects those repairs.</strong> An invalid <code class="language-plaintext highlighter-rouge">repair_road</code> is validated and declined
<em>before</em> it consumes anything — zero resources, no effect on the world. And the conformance metric
counts the agent’s <em>attempt</em>. So a guard that intercepted the attempt would do exactly one thing:
make the conformance number go up by <strong>hiding the agent’s behavior from the record.</strong> The world would
play out identically — same lives, same cost — and the scoreboard would look better.</p>

<p>That is the cleanest example I’ve hit of an <strong>outcome-neutral metric</strong>: a number you can move without
changing anything real. Building the guard would have been <em>reward-hacking my own benchmark.</em> I didn’t
build it. The honest version of the question isn’t “how do I make the number go up” — it’s “is the
behavior actually fixable, and does fixing it matter?”</p>

<p>So I tested that instead: I gave just the infra agent a <strong>stronger model</strong> (<code class="language-plaintext highlighter-rouge">qwen3.5-plus</code> instead of
<code class="language-plaintext highlighter-rouge">flash</code>) and measured, changing nothing else.</p>

<div class="readout-table">
  <div class="rt-cap"><span class="sq"></span>Infra agent: flash vs plus (model isolated, 5 seeds)</div>
  <table class="rt">
    <thead>
      <tr><th>Signal</th><th>flash</th><th>plus</th><th>Δ</th></tr>
    </thead>
    <tbody>
      <tr class="win"><td>impossible-repair rule</td><td>0.560</td><td>0.957</td><td><strong>+0.40</strong></td></tr>
      <tr class="win"><td>infra conformance</td><td>0.863</td><td>0.986</td><td>+0.123 &nbsp;(all 5 seeds)</td></tr>
      <tr><td>lives saved</td><td>103.6</td><td>103.8</td><td>flat &nbsp;(p = 1.0)</td></tr>
      <tr class="lose"><td>cost / run</td><td>$0.041</td><td>$0.054</td><td><strong>+33%</strong></td></tr>
    </tbody>
  </table>
</div>

<p>So the stickiness was a <strong>model-capability floor</strong>, not a prompt bug: the bigger model gates the
preconditions the smaller one ignores. A real finding — but look at the trade. It buys near-perfect
conformance on an <em>outcome-neutral</em> rule (the bad repairs cost no lives to begin with) for <strong>+33%
cost.</strong> Paying a third more to perfect a metric that doesn’t move lives, on an arm whose whole pitch
is cost-efficiency, is the wrong default.</p>

<p>So it ships as an <strong>opt-in operating mode</strong> — one flag, <code class="language-plaintext highlighter-rouge">--role-model infrastructure=qwen3.5-plus</code> —
not the published default. Flip it when discipline matters more than dollars; leave it off for the
lives-per-dollar story. The <em>finding</em> (it’s a capability floor) is the durable result, independent of
which default you choose.</p>

<h2 id="lever-3--the-one-that-actually-paid-stop-re-sending-the-prompt">Lever 3 — the one that actually paid: stop re-sending the prompt</h2>

<p>With lives ruled out and conformance either free (doctrine) or expensive (infra model), I turned to
the axis the society can actually win on: <strong>cost.</strong> And here the harness did its best work as a
<em>profiler</em> before it did anything as a judge.</p>

<p>Where does the money go? The commander sends <strong>31,900 prompt tokens per run but only 2,300 of
completion.</strong> Decomposing one call: a <strong>941-token system prompt re-sent on every single tick</strong>, plus
only ~160 tokens of actual world observation. Across all six agents, <strong>~85% of a run’s prompt tokens
are the same static prefixes, re-sent every tick</strong> — roughly <strong>60% of total cost</strong> is the model
re-reading instructions it already read last tick.</p>

<p>The obvious fix is <em>caching</em> — most providers bill a repeated prefix at a discount. So I probed it: a
~1,600-token stable prefix, sent three times in a row, on both Qwen models. The response told me
plainly:</p>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">prompt_tokens_details: { text_tokens: 1589 }</code> — <strong>no <code class="language-plaintext highlighter-rouge">cached_tokens</code> field, no discount, full price
every call.</strong></p>
</blockquote>

<p>DashScope’s international compatible-mode endpoint doesn’t cache our prompts. That’s a <em>clean negative
result</em> worth knowing: it means our cost ledger is <strong>accurate, not pessimistic</strong> — there’s no free
accounting win hiding in cache hits. The only way to cut a re-sent prompt is to <strong>make it shorter.</strong></p>

<p>Doctrine is off-limits (it’s the conformance lever from Lever 1) and the role instructions are
behavioral, so the target was the <strong>output contract</strong> — the JSON-format boilerplate every agent
carries. I compacted the multi-line schema to one line, deduplicated rules that were stated twice, and
tightened the proposal descriptions — keeping every capability and field name, just terser. Commander
prefix: <strong>941 → 835 tokens.</strong> Then the paired A/B, against an identical baseline where <em>only the
contract differs:</em></p>

<div class="readout-table">
  <div class="rt-cap"><span class="sq"></span>Trimmed contract vs full — paired, 5 seeds</div>
  <table class="rt">
    <thead>
      <tr><th>Signal</th><th>full</th><th>trimmed</th><th>Δ</th></tr>
    </thead>
    <tbody>
      <tr class="win"><td>cost / run</td><td>$0.0411</td><td>$0.0353</td><td><strong>−14.0%</strong></td></tr>
      <tr class="win"><td>lives per dollar</td><td>2,522</td><td>3,046</td><td><strong>+21%</strong></td></tr>
      <tr><td>lives saved</td><td>103.6</td><td>107.6</td><td>+4.0 &nbsp;(up, not significant)</td></tr>
      <tr><td>conformance</td><td>0.916</td><td>0.879</td><td>−0.037 &nbsp;(p = 0.375, n.s.)</td></tr>
    </tbody>
  </table>
</div>

<p>A real, largely <em>deterministic</em> <strong>14% cost cut</strong> — the token reduction is fixed; only the small
completion varies — for a <strong>21% gain in lives-per-dollar</strong>, the headline efficiency number. Lives even
drifted up. The one thing to respect: conformance ticked down 0.037, but the sign test says that’s not
a credible effect (p=0.375), and it sits inside the run-to-run band conformance has always wandered in
(0.85–0.92). By the same bar I used to <em>reject</em> the +16-life ghost last post, I can’t <em>claim</em> this
conformance dip either — so I kept the trim and logged the dip as a watch-item, not a regression.</p>

<p>The deeper lesson hid in the disappointment: the pure-redundancy trim was tiny (~16 tokens). Most of
that 941-token prefix is <strong>irreducible</strong> — doctrine the agents need, decision vocabulary they act on,
a schema that keeps the JSON valid. The society’s ~$0.04/run is <em>mostly structural.</em> −14% is close to
the safe ceiling without touching doctrine or model tier. Worth banking; not a bottomless well.</p>

<h2 id="the-pattern-four-levers-one-bar">The pattern: four levers, one bar</h2>

<p>Before chasing each lever I made a workflow of read-only agents scope it against one question — <em>does
moving this metric change a real outcome?</em> It skipped four backlog ideas outright (a deadline-sort for
a failure mode that’s already near zero; reducing “redundant” bids the auction ignores for free; a
temperature sweep premised on a cost number that turned out wrong). Each was an outcome-neutral
mirage, the I1-guard pattern again: a number you can move that moves nothing else.</p>

<p>What <em>survived</em> the bar is exactly the society’s honest story:</p>

<ol>
  <li><strong>Doctrine</strong> raises conformance on every seed, free of lives cost.</li>
  <li><strong>Conformance has a price ceiling</strong> — the last stubborn role needs a bigger model, which costs
more than the (outcome-neutral) metric is worth as a default, so it’s a switch.</li>
  <li><strong>Cost is real and movable</strong> — −14% by not re-sending what the model already read, the cap set by
how much of the prompt is genuinely load-bearing.</li>
</ol>

<p>No grand lives breakthrough. But three claims I can defend in front of a judge, and a fistful of
features I <em>didn’t</em> ship because the measurement said they’d only flatter the scoreboard.</p>

<h2 id="the-takeaway">The takeaway</h2>

<p>Last post’s lesson was <em>a single measurement is a coin flip wearing a lab coat</em> — pair it, test it,
know when to stop. This session added the sharper one:</p>

<p><strong>Before you optimize a metric, prove the metric does something.</strong> The most seductive failure isn’t a
noisy win — it’s a <em>clean</em> win on a number that’s decoupled from reality. I could have made my
conformance score jump by intercepting decisions the engine already discards; it would have demoed
beautifully and meant nothing. The guard against that isn’t more statistics. It’s tracing the metric
back to an outcome — lives, dollars, missions — and refusing to celebrate a move that doesn’t reach
one.</p>

<p>Make it measurable. Believe only what survives the measurement. And check that the thing you’re
measuring is connected to the thing you actually care about.</p>

<p><strong>Try it live:</strong> <a href="https://aftershock.redoubtlabs.dev">https://aftershock.redoubtlabs.dev</a> · <strong>Read the code:</strong> <a href="https://github.com/bluntmachetti/aftershock">https://github.com/bluntmachetti/aftershock</a>
(the levers are in
<a href="https://github.com/bluntmachetti/aftershock/blob/main/docs/FIELD-NOTES.md"><code class="language-plaintext highlighter-rouge">docs/FIELD-NOTES.md</code></a>
§18–21; the cost trim is <code class="language-plaintext highlighter-rouge">--role-model</code> / the output contract)</p>

<p><em>Built with Qwen Cloud (<code class="language-plaintext highlighter-rouge">qwen3.5-flash</code> / <code class="language-plaintext highlighter-rouge">qwen3.5-plus</code> / <code class="language-plaintext highlighter-rouge">qwen3-max</code> via DashScope) and Alibaba
Cloud ECS, for the Qwen Cloud Global AI Hackathon.</em></p>]]></content><author><name>Kenny Ademolu</name></author><summary type="html"><![CDATA[With the measurement harness built, I finally tuned Aftershock's Qwen agent society. The ruler kept saying a new kind of no: not 'that's noise' but 'that would work and still change nothing real.' I almost shipped a fix whose only effect was to make a conformance metric look better. A field report on outcome-neutral metrics — and the one lever (a −14% cost trim) that survived the bar.]]></summary></entry><entry><title type="html">Build the ruler first. It killed our biggest feature — and a +16-life win that wasn’t real.</title><link href="https://aftershock.redoubtlabs.dev/2026/06/15/build-the-ruler-first.html" rel="alternate" type="text/html" title="Build the ruler first. It killed our biggest feature — and a +16-life win that wasn’t real." /><published>2026-06-15T22:00:00+00:00</published><updated>2026-06-15T22:00:00+00:00</updated><id>https://aftershock.redoubtlabs.dev/2026/06/15/build-the-ruler-first</id><content type="html" xml:base="https://aftershock.redoubtlabs.dev/2026/06/15/build-the-ruler-first.html"><![CDATA[<p>My backlog for <a href="https://github.com/bluntmachetti/aftershock"><strong>Aftershock</strong></a> had a clear headliner.
Of ~44 ideas for making the Qwen agent society save more lives, one was marked <em>the single biggest
lever</em>: a smarter resource auction (partial grants instead of all-or-nothing), hypothesized at
<strong>+10–15 lives a run</strong>. The obvious move was to build it.</p>

<p>I didn’t build it. I built a <em>ruler</em> first — the boring statistical plumbing that tells you whether
a change actually did anything. And the ruler earned its keep three times over in one sitting: it
<strong>killed the headliner</strong> before I wrote a line of it, it <strong>caught a +16-life win that wasn’t real</strong>,
and it made me <strong>put a caveat on my own flagship number</strong>.</p>

<p>This is a post about the least glamorous part of the project — measurement — and why it turned out
to be the most valuable.</p>

<h2 id="why-a-ruler-before-any-tuning">Why a ruler, before any tuning</h2>

<p>Aftershock’s engine is byte-deterministic: same seed, same disaster, same outcome. But the <em>agents</em>
are not. The published society result — <code class="language-plaintext highlighter-rouge">103.2 ± 23.6</code> lives — has a <code class="language-plaintext highlighter-rouge">±</code> for a reason, and the first
thing the ruler did was tell me exactly what that <code class="language-plaintext highlighter-rouge">±</code> is made of.</p>

<p>Two cheap experiments:</p>

<ul>
  <li><strong>Does Qwen Cloud honor a sampling <code class="language-plaintext highlighter-rouge">seed</code>?</strong> I threaded a deterministic per-call seed through every
request and ran the same world twice. The two runs diverged on the first tick, exactly like two
un-seeded runs. <strong>DashScope accepts <code class="language-plaintext highlighter-rouge">seed</code> but doesn’t make sampling reproducible</strong> — so the LLM
arms are irreducibly stochastic, and that <code class="language-plaintext highlighter-rouge">±</code> really is sampling noise, not measurement slop.</li>
  <li><strong>How much of the noise is the <em>model</em>, and how much is the <em>world</em>?</strong> Running each seed three
times and decomposing the variance: <strong>79% of it is which disaster you drew</strong> (between-seed), only
<strong>21% is the model’s run-to-run wobble</strong> (within-seed).</li>
</ul>

<p>That second number is the whole game. If most of your variance is the scenario, then comparing a
<em>mean</em> against a <em>mean</em> is mostly comparing coin flips — unless you <strong>pair</strong>: run the control and the
treatment on the <em>same</em> seeds and difference out the world. Concretely, to detect a +10-life effect
at decent power you need <strong>~10 paired seeds, versus ~45 unpaired</strong>. Same data, a quarter of the runs,
because pairing deletes the 79%.</p>

<p>So the ruler is: run both arms on identical seeds, take the per-seed difference, and judge it with a
sign test, a bootstrap confidence interval, and a power curve — <code class="language-plaintext highlighter-rouge">aftershock ablation</code>. Nothing fancy.
Just enough to stop me believing a number I shouldn’t.</p>

<h2 id="episode-1--the-diagnostic-killed-the-headliner">Episode 1 — the diagnostic killed the headliner</h2>

<p>The “biggest lever” exists to fix a specific pathology: a <strong>priority inversion</strong>. Under all-or-nothing
granting, a high-priority incident that needs three ambulances can lose the whole pool to a
later, lower-priority incident that happens to fit the two that are left. Partial grants would fix
that. Worth +10–15 lives — <em>if it happens.</em></p>

<p>So before building the fix, I built a diagnostic that reads the recorded auction outcomes and counts
how often it actually happens. The answer, across nine society runs:</p>

<p><strong>Zero.</strong></p>

<p>Then I made the world harder — I added a knob to tighten the resource pools — figuring scarcity would
surely manufacture the contention. Still zero. I cranked it to the harshest setting the sim allows
(every pool at 2, where a <em>fifth</em> of all incidents fail outright):</p>

<div class="readout-table">
  <div class="rt-cap"><span class="sq"></span>Priority inversions found — the pathology the "biggest lever" fixes</div>
  <table class="rt">
    <thead>
      <tr><th>World</th><th>Society runs</th><th>Priority inversions</th></tr>
    </thead>
    <tbody>
      <tr class="win"><td>default</td><td>9</td><td><strong>0</strong> &nbsp;(of 59 contested losses)</td></tr>
      <tr class="win"><td>tight pools</td><td>6</td><td><strong>0</strong> &nbsp;(of 74 contested)</td></tr>
      <tr class="lose"><td>harshest (all pools = 2)</td><td>5</td><td><strong>6</strong> &nbsp;(of 794 losses — &lt;1%)</td></tr>
    </tbody>
  </table>
</div>

<p>Across the default and tight worlds: <strong>133 contested auction losses, every single one legitimate</strong> —
the loser always had lower-or-equal priority than the winner. The auction’s arbitration is just
<em>correct</em>: it serves the highest-priority incident first, and the agents don’t over-request in the
way that would let a low-priority bid steal the remainder. Only at brutal scarcity do a handful of
inversions appear, and even then they’re dwarfed 70-to-1 by plain shortage (the pool is simply empty
— there’s nothing for a partial grant to split).</p>

<p>The verdict wrote itself: <strong>don’t build the lever.</strong> It optimizes a problem this system doesn’t have.
That’s the harness paying for itself before it cost a thing — a feature un-built is a feature you
don’t have to maintain, document, or quietly regret.</p>

<p>(A humbling footnote: the <em>first</em> version of that inversion detector was dead code — by the
resolver’s ordering it could never actually fire — and an adversarial code review caught it. Even the
ruler needed measuring. I rebuilt it to reconstruct winners-versus-losers from the recorded grants,
and <em>then</em> trusted the zeros.)</p>

<h2 id="episode-2--the-16-that-wasnt">Episode 2 — the +16 that wasn’t</h2>

<p>Fine: the auction isn’t the bottleneck on the easy task. But the easy task is <em>easy</em> — ~96% of
incidents get resolved, so there’s barely any room for any change to move lives. The honest next
question: under genuine triage — a world where you <em>can’t</em> save everyone and the order you serve
people in decides who lives — does the society’s coordination actually beat the uncoordinated swarm
by more?</p>

<p>I dialed in that world (the harshest setting: lives saved ≈ lives lost) and ran a paired
society-vs-swarm ablation. Five seeds. The result looked <em>great</em>:</p>

<blockquote>
  <p><strong>Δ = +16.2 lives</strong>, 95% CI <strong>[+3.2, +29.6]</strong> — excludes zero. Society stable at 63–72 lives across
every seed; swarm volatile (32–66), collapsing on the two hard draws (39 and 32 lives).</p>
</blockquote>

<p>A clean story practically wrote itself: <em>coordination buys graceful degradation under stress.</em> The
harness’s own auto-verdict even printed <strong>“credible improvement.”</strong> I wanted to believe it.</p>

<p>But the same readout had two warnings I’d built in precisely so I couldn’t ignore them: the <strong>sign
test was non-significant</strong> (p=0.375) and the <strong>statistical power was 0.57</strong>. The confidence interval
said yes; the more conservative tests said <em>not yet.</em> The honest move with a disagreement like that
is not to pick the answer you like — it’s to add seeds. So I added six more (the harness resumes the
runs it already has, so only the new ones cost anything) and re-ran at eleven.</p>

<div class="readout-table">
  <div class="rt-cap"><span class="sq"></span>Society vs swarm, harsh world — the same effect at n=5 and n=11</div>
  <table class="rt">
    <thead>
      <tr><th>Seeds</th><th>Δ lives</th><th>95% CI</th><th>Sign test</th><th>Power</th></tr>
    </thead>
    <tbody>
      <tr class="lose"><td>n = 5</td><td><strong>+16.2</strong></td><td>[+3.2, +29.6] — excludes 0</td><td>p = 0.375</td><td>0.57</td></tr>
      <tr class="win"><td>n = 11</td><td><strong>+4.7</strong></td><td>[−4.0, +14.7] — <em>includes 0</em></td><td>p = 1.0</td><td>0.15</td></tr>
    </tbody>
  </table>
</div>

<p>The effect <strong>evaporated.</strong> Four of the six new seeds came back with the <em>swarm beating the society</em>. The
entire +16 had been carried by two lucky draws where the swarm happened to faceplant; the “society is
rock-stable” story was the same small-sample mirage (at eleven seeds the society’s range is 32–80,
not the tidy 63–72 I’d seen at five). There is <strong>no detectable lives advantage</strong> here. The power
curve says confirming even the residual +4.7 would take ~88 seeds — which is the harness’s polite way
of saying <em>stop.</em></p>

<p>This is the single most important thing the ruler did. A +16-life result with a confidence interval
that excludes zero is <em>exactly</em> the kind of finding you screenshot, put in a slide, and ship. It was
noise. I caught it because I’d committed in advance to a test I couldn’t argue with after the fact.</p>

<h2 id="episode-3--turning-the-ruler-on-my-own-headline">Episode 3 — turning the ruler on my own headline</h2>

<p>If a +16 can be a ghost, what about the project’s flagship claim — that the coordination protocol is
worth <strong>+28 lives</strong>? I owed it the same scrutiny, so I ran the <em>already-published</em> numbers through the
same paired test. The result, to my relief, held up where the +16 didn’t — but not cleanly:</p>

<ul>
  <li><strong>Directionally solid:</strong> society ≥ swarm on <strong>all five</strong> seeds (four wins, one tie, zero losses).
Unlike the harsh-world ghost that went both ways, this gap is real in sign. The qualitative claim —
<em>the auction helps</em> — survives.</li>
  <li><strong>Magnitude soft:</strong> the precise “+28” is leaned on hard by a single seed (+88 there; the other four
average +12.5), the sign test is p=0.125, and the power is 0.42. To put a tight interval on the
<em>number</em> you’d want ~25 seeds.</li>
</ul>

<p>So I’m keeping the claim and adding a caveat I can defend: <em>the coordination protocol reliably helps;
the headline figure is an n=5 mean with a wide interval.</em> That’s a weaker sentence than “+28 lives,”
and it’s the true one.</p>

<h2 id="what-the-ruler-cost-and-what-it-bought">What the ruler cost, and what it bought</h2>

<p>The whole measurement campaign — 41 paired runs across every world — cost <strong>$1.41</strong> in Qwen Cloud
tokens, tallied from the run ledgers. For that, I got three results I’d have paid far more for in
wasted effort and overconfidence:</p>

<ol>
  <li><strong>Don’t build the “biggest lever.”</strong> It fixes a pathology that occurs &lt;1% of the time.</li>
  <li><strong>There’s no lives edge under triage.</strong> The +16 was a false positive; the honest story for the
society is cost-efficiency and discipline, not out-saving the swarm under scarcity.</li>
  <li><strong>Caveat the +28.</strong> Real in direction, soft in magnitude.</li>
</ol>

<p>None of those are features. Two are flat “don’ts” and one is a hedge. And they’re the most valuable
output of the session — because the alternative was building a feature against a problem that isn’t
there, and believing a win that wasn’t real, in a slide deck, in front of judges.</p>

<h2 id="the-takeaway">The takeaway</h2>

<p>In a stochastic system, <strong>a single measurement is a coin flip wearing a lab coat.</strong> The plumbing
that protects you from it — pair to kill the variance you don’t care about, judge with a test you
picked <em>before</em> you saw the answer, and let a power curve tell you when to stop — isn’t bureaucracy.
It’s the difference between knowing and hoping. Build that ruler before you build the thing you’re
itching to build, because the ruler’s best days are the ones where it tells you <em>no.</em></p>

<p>And hold your own dashboard to the same bar: my ablation tool’s auto-verdict cheerfully called the
+16 “credible,” and the sign test is the only reason I didn’t believe it. The tool that keeps you
honest still needs you to read all of it.</p>

<p>Make it measurable. Then believe only the part that survives the measurement.</p>

<p><strong>Try it live:</strong> <a href="https://aftershock.redoubtlabs.dev">https://aftershock.redoubtlabs.dev</a> · <strong>Read the code:</strong> <a href="https://github.com/bluntmachetti/aftershock">https://github.com/bluntmachetti/aftershock</a>
(the harness is <code class="language-plaintext highlighter-rouge">aftershock ablation</code> / <code class="language-plaintext highlighter-rouge">aftershock diagnose</code>; the findings are in
<a href="https://github.com/bluntmachetti/aftershock/blob/main/docs/FIELD-NOTES.md"><code class="language-plaintext highlighter-rouge">docs/FIELD-NOTES.md</code></a> §13–17)</p>

<p><em>Built with Qwen Cloud (<code class="language-plaintext highlighter-rouge">qwen3.5-flash</code> / <code class="language-plaintext highlighter-rouge">qwen3.5-plus</code> / <code class="language-plaintext highlighter-rouge">qwen3-max</code> via DashScope) and Alibaba
Cloud ECS, for the Qwen Cloud Global AI Hackathon.</em></p>]]></content><author><name>Kenny Ademolu</name></author><summary type="html"><![CDATA[Before tuning Aftershock's Qwen agent society, I built the measurement: paired ablations, a power curve, and free diagnostics over the run records. Then the measurement did its job — it killed the backlog's biggest planned feature before I wrote a line of it, caught a +16-life 'win' that evaporated when I added seeds, and made me caveat my own headline number. A field report on not fooling yourself.]]></summary></entry><entry><title type="html">We drew the agent auction on the map. A review caught it pointing at the wrong district.</title><link href="https://aftershock.redoubtlabs.dev/2026/06/15/we-drew-the-auction-on-the-map.html" rel="alternate" type="text/html" title="We drew the agent auction on the map. A review caught it pointing at the wrong district." /><published>2026-06-15T16:00:00+00:00</published><updated>2026-06-15T16:00:00+00:00</updated><id>https://aftershock.redoubtlabs.dev/2026/06/15/we-drew-the-auction-on-the-map</id><content type="html" xml:base="https://aftershock.redoubtlabs.dev/2026/06/15/we-drew-the-auction-on-the-map.html"><![CDATA[<p>The headline number in <a href="https://github.com/bluntmachetti/aftershock"><strong>Aftershock</strong></a> is that a
coordination protocol is worth +28 lives a run — the same five <code class="language-plaintext highlighter-rouge">qwen3.5-flash</code> workers save 103
lives instead of 75 once you put an auction between them and the shared pool of ambulances, rescue
crews, and fire engines. The protocol-less swarm burns its turns racing for resources that are
already gone; the society resolves that contention <em>before</em> anyone acts.</p>

<p>That sentence is the entire project. And until last week you could only read it — in a scrolling
text feed of <code class="language-plaintext highlighter-rouge">granted</code> / <code class="language-plaintext highlighter-rouge">pool exhausted</code> rulings off to the side of the map. The thing that
matters most was the thing you couldn’t see happen.</p>

<p>So this build was about making the mechanism legible: a Mission Control rebuild of the map that
draws the auction itself, live, on the city. It’s also a small parable about how a <em>picture</em> can
lie exactly as easily as a number — and on a project whose whole pitch is honesty, the picture
doesn’t get a pass.</p>

<h2 id="from-map-to-mission-control">From “map” to mission control</h2>

<p>The old map was honest but generic: district blocks, mission pins, a panic gauge. Fine. But it
read like a dashboard, not an emergency operations center — and it buried the one event you’d want
a commander watching for.</p>

<p>The rebuild is an EOC command view. A condition state up top (RED/AMBER/BLUE/GREEN, driven by the
nearest deadline, worst severity, and public panic), a tile map of the city, and — the point of the
whole exercise — a <strong>contention overlay</strong>.</p>

<p>When two incidents reach for the last unit of a resource in the same tick, the map draws it: a
dashed line from the district that <em>lost</em> to the district that <em>won</em>, labeled with the resource
(<code class="language-plaintext highlighter-rouge">AMB CONTESTED</code>, <code class="language-plaintext highlighter-rouge">RPR CONTESTED</code>), a halo on both incidents. You watch the auction arbitrate the
Qwen agents’ requests in real time. The <code class="language-plaintext highlighter-rouge">qwen3.5-plus</code> commander and the kernel’s auction stop
being a feed you skim and become a thing you see resolve, tick by tick.</p>

<p>And it’s derived from data that was already there. Every tick record carries the agents’ typed
<code class="language-plaintext highlighter-rouge">resource_request</code> proposals and the auction’s rulings. The overlay is a pure function of those —
no new engine state, no new field, nothing for the deterministic core to even notice. Same pack,
same seed, byte-identical run, now with the contention drawn on top.</p>

<h2 id="the-part-a-review-caught">The part a review caught</h2>

<p>Here’s where it gets honest. The first version of that overlay was subtly wrong, and it took an
automated code review on the pull request to catch it.</p>

<p>The auction can grant the same resource to several incidents before the pool runs dry. Picture one
tick, three incidents reaching for ambulances against a pool that can only cover two of them:</p>

<table>
  <thead>
    <tr>
      <th>incident</th>
      <th>district</th>
      <th>ambulance</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>m1</td>
      <td>Harbor</td>
      <td><strong>granted</strong></td>
    </tr>
    <tr>
      <td>m2</td>
      <td>Hospital</td>
      <td><strong>granted</strong> (the last one)</td>
    </tr>
    <tr>
      <td>m3</td>
      <td>Market</td>
      <td><strong>lost</strong></td>
    </tr>
  </tbody>
</table>

<p>m3 lost. But <em>to whom?</em> My first cut linked every loser to the <strong>first</strong> winner it happened to
process — here, m1 in Harbor. So the map drew Market’s “you lost this” arrow at Harbor, when the
auction’s own ruling says plainly: <code class="language-plaintext highlighter-rouge">pool exhausted: ambulance granted to m2</code> — m3 lost the <em>last</em>
unit to m2, in Hospital. The picture pointed at the wrong district.</p>

<p>The reviewer flagged it as a misattribution, and it wasn’t theoretical — it was live in the demo
data. The very first contested tick of our headline society run drew the contention line at the
wrong district. A plausible-looking arrow, confidently wrong.</p>

<p>The fix was to stop guessing and read what the auction already said: parse the winner named in each
loser’s own ruling, and link to <em>that</em> district. It also made the code simpler — the whole
“figure out who the winner probably was” scaffolding just deleted.</p>

<p>I keep a rule for the benchmark: never claim a number you didn’t measure on identical worlds. This
was the same rule, wearing a different hat. <strong>A visualization is an inference too, and it earns the
same scrutiny as a number</strong> — more, even, because a clean line on a map <em>feels</em> like ground truth
in a way a table never does. The map can be confidently, beautifully wrong. On a project that puts
<code class="language-plaintext highlighter-rouge">REAL / MAPPED / INFERRED / SYNTHETIC</code> labels on every field precisely so nothing overclaims, an
overlay that quietly fingers the wrong district is the same sin in a prettier font.</p>

<h2 id="keeping-a-reskin-honest">Keeping a reskin honest</h2>

<p>It’s “just frontend,” but the failure modes of a frontend change on a project like this are
specific, so it got the engine treatment:</p>

<ul>
  <li><strong>The color contract is frozen.</strong> Society stays cyan, the baselines stay amber — the same coding
the side-by-side compare view leans on. The redesign added exactly one new color (a caution
yellow for contention) and reused the existing signals for everything else, so no other view
shifted a pixel.</li>
  <li><strong>The honesty surfaces stayed first-class.</strong> The reality strip — real first-on-scene latency vs.
the agents’ simulated response, the <code class="language-plaintext highlighter-rouge">INFERRED</code> badge on lives-at-risk, the never-fabricated-when-
null rule — all survived untouched, including on the live NYC Hurricane Ida pack with its borough
names and provenance.</li>
  <li><strong>The blast radius was provable.</strong> I pulled the rich incident markers into a shared module so the
compare view’s two synced maps render from the <em>exact same code</em> but never inherit the overlay —
the one map that should change changed, and the one that shouldn’t was untouched by construction,
not by hope.</li>
  <li><strong>Determinism never moved.</strong> Frontend-only, so the <code class="language-plaintext highlighter-rouge">aftershock verify</code> digest check couldn’t
regress — and it didn’t.</li>
</ul>

<p>Then it went out the way everything does: local → staging → production, verified at each hop, live
now at the public demo.</p>

<h2 id="the-takeaway">The takeaway</h2>

<p>The benchmark exists to make the <em>result</em> falsifiable: here’s the baseline, here are the identical
worlds, here’s the measured gain. This build was the same instinct aimed at the <em>mechanism</em>: make
the coordination you can’t otherwise see legible enough to watch — and then hold the picture to the
same bar as the numbers, including the part you only find when someone reviews it and asks “wait,
who actually won?”</p>

<p>Make the mechanism visible. Then make sure the visible thing is telling the truth.</p>

<p><strong>Try it live:</strong> <a href="https://aftershock.redoubtlabs.dev">https://aftershock.redoubtlabs.dev</a> — load a society run and scrub to a contested
tick · <strong>Read the code:</strong> <a href="https://github.com/bluntmachetti/aftershock">https://github.com/bluntmachetti/aftershock</a></p>

<p><em>Built with Qwen Cloud (<code class="language-plaintext highlighter-rouge">qwen3.5-flash</code> / <code class="language-plaintext highlighter-rouge">qwen3.5-plus</code> / <code class="language-plaintext highlighter-rouge">qwen3-max</code> via DashScope) and Alibaba
Cloud ECS, for the Qwen Cloud Global AI Hackathon.</em></p>]]></content><author><name>Kenny Ademolu</name></author><summary type="html"><![CDATA[Aftershock's whole result rests on one mechanic: an auction that resolves resource contention between Qwen agents before they act. We rebuilt the observatory's map into a Mission Control view that draws that auction live — and a code review caught the overlay blaming the wrong winning district. Making the mechanism visible meant holding the picture to the same honesty bar as the numbers.]]></summary></entry><entry><title type="html">We added native function calling. The benchmark told us to turn it off.</title><link href="https://aftershock.redoubtlabs.dev/2026/06/14/we-added-function-calling-the-benchmark-told-us-to-turn-it-off.html" rel="alternate" type="text/html" title="We added native function calling. The benchmark told us to turn it off." /><published>2026-06-14T16:00:00+00:00</published><updated>2026-06-14T16:00:00+00:00</updated><id>https://aftershock.redoubtlabs.dev/2026/06/14/we-added-function-calling-the-benchmark-told-us-to-turn-it-off</id><content type="html" xml:base="https://aftershock.redoubtlabs.dev/2026/06/14/we-added-function-calling-the-benchmark-told-us-to-turn-it-off.html"><![CDATA[<p>A confession about hackathon incentives. The Qwen Cloud judging rubric weights <em>“sophisticated
use of Qwen Cloud APIs”</em> at about 30%, and <a href="https://github.com/bluntmachetti/aftershock"><strong>Aftershock</strong></a>’s
agent society had, until last week, been talking to Qwen the unglamorous way: every agent returns
strict JSON, the engine parses and validates it. Functional, but it doesn’t <em>look</em> like you’re
using the platform’s fanciest toy. So I did the obvious thing and wired up <strong>native function
calling</strong> — per-role <code class="language-plaintext highlighter-rouge">tools</code>, <code class="language-plaintext highlighter-rouge">tool_choice</code>, <code class="language-plaintext highlighter-rouge">parallel_tool_calls</code>, a dedicated <code class="language-plaintext highlighter-rouge">no_op</code> idle tool,
the works.</p>

<p>Then I did the thing I keep telling everyone else to do, and which is the entire point of this
project: I benchmarked it before believing in it.</p>

<p>The benchmark told me to turn it off.</p>

<p>This post is that result — because a negative result you measured honestly is worth more than a
feature you shipped on faith.</p>

<h2 id="what-native-function-calling-replaced">What “native function calling” replaced</h2>

<p>In JSON mode, each agent’s system prompt carries a compact prose contract — <em>here are your
actions, here are the fields, return JSON</em> — and the model returns a JSON object the engine
validates. In tool mode, that same action vocabulary becomes a set of OpenAI-style <code class="language-plaintext highlighter-rouge">tools</code>
definitions sent on every request, and the model emits structured <code class="language-plaintext highlighter-rouge">tool_calls</code> instead. Same
decisions, same auction, same negotiation protocol underneath. The <em>only</em> thing that changed is
how the action space is described to the model and how the model hands its choices back.</p>

<p>I kept the change behind a flag (<code class="language-plaintext highlighter-rouge">--society-tools</code>) and a <code class="language-plaintext highlighter-rouge">force_tools</code> switch, so I could run the
<em>exact</em> same five paired seeds both ways and let the numbers decide. Same disasters, byte for
byte. Only the calling convention differs.</p>

<h2 id="the-numbers">The numbers</h2>

<div class="readout-table">
  <div class="rt-cap"><span class="sq"></span>Society mode · 5 paired seeds</div>
  <table class="rt">
    <thead>
      <tr>
        <th>Society mode</th>
        <th>Lives saved (μ ± σ)</th>
        <th>Missions failed</th>
        <th>Cost / run</th>
        <th>Latency / run</th>
      </tr>
    </thead>
    <tbody>
      <tr class="win">
        <td>JSON contracts <span class="win-badge">default</span></td>
        <td><strong>103.2 ± 23.6</strong></td>
        <td><strong>0.4</strong></td>
        <td><strong>$0.042</strong></td>
        <td>120 s</td>
      </tr>
      <tr class="lose">
        <td>Native function calling</td>
        <td>98.2 ± 23.2</td>
        <td>0.8</td>
        <td>$0.083</td>
        <td>297 s</td>
      </tr>
    </tbody>
  </table>
</div>

<p>Read that top to bottom. Tool calling held lives saved <strong>within the noise</strong> — 98.2 vs 103.2 sits
comfortably inside one standard deviation (±23) — while <strong>cost roughly doubled and latency rose
~2.5×</strong>. The one place it moved measurably in the <em>wrong</em> direction was missions failed: 0.8 vs
0.4, twice as many lapsed deadlines, plausibly downstream of the higher latency (the
<code class="language-plaintext highlighter-rouge">qwen3.5-plus</code> commander even hit a couple of request timeouts under the heavier payloads).</p>

<p>If you’re tempted to read the 5-life dip as a real regression, the paired-seed view talks you out
of it — tool mode was lower on four seeds, higher on one:</p>

<table>
  <thead>
    <tr>
      <th>seed</th>
      <th>11</th>
      <th>23</th>
      <th>37</th>
      <th>42</th>
      <th>57</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>JSON lives</td>
      <td>140</td>
      <td>86</td>
      <td>81</td>
      <td>98</td>
      <td>111</td>
    </tr>
    <tr>
      <td>tool lives</td>
      <td>138</td>
      <td>79</td>
      <td>90</td>
      <td>87</td>
      <td>97</td>
    </tr>
  </tbody>
</table>

<p>That’s noise with a faint downward lean, not a signal. So the honest summary is brutal in its
simplicity: <strong>native function calling cost twice as much to do the same job, slightly worse.</strong></p>

<h2 id="why--and-why-no-amount-of-prompting-saves-it">Why — and why no amount of prompting saves it</h2>

<p>The cause isn’t a bad implementation or an untuned prompt. It’s structural, and it’s worth
internalizing if you build multi-agent systems.</p>

<p>A society run makes roughly <strong>240 model calls</strong> — six agents, dozens of ticks. In JSON mode the
action vocabulary rides along as a ~450-token prose contract. In tool mode the equivalent <code class="language-plaintext highlighter-rouge">tools</code>
schema is <strong>~1,000 tokens</strong>, and — this is the load-bearing sentence — <strong>it is re-sent on every
single one of those 240 calls.</strong> The schema is pure repeated input tokens. The most expensive
seat in the house, the <code class="language-plaintext highlighter-rouge">qwen3.5-plus</code> commander, ate 59% of the run’s cost on its own; the five
flash workers split the rest, their prompts dominated by that resent schema.</p>

<p>I genuinely tried to schema-trim my way out of it. I projected every option: strip the
auto-generated pydantic <code class="language-plaintext highlighter-rouge">title</code>/<code class="language-plaintext highlighter-rouge">default</code> noise, compact the descriptions, even gut them to empty
strings. The floor — descriptions deleted entirely — is about <strong>$0.069/run</strong>. Still above the JSON
path’s $0.042, and still above the single-<code class="language-plaintext highlighter-rouge">qwen3-max</code>-does-everything baseline (~$0.06). You can’t
trim a per-call tax down to nothing when you pay it 240 times.</p>

<h2 id="the-decision-default-off-available-and-measured">The decision: default off, available and measured</h2>

<p>So Aftershock ships with <strong>JSON contracts as the default</strong> — the cost-optimal path, and the one
the published headline (“a society of small models matches a <code class="language-plaintext highlighter-rouge">qwen3-max</code> solo agent at ~35% lower
cost”) actually reflects. Native function calling stays <strong>implemented, tested, and benchmarked</strong>,
one flag away (<code class="language-plaintext highlighter-rouge">aftershock run --arm society --society-tools</code>), with its full ablation published in
the repo and in <a href="https://github.com/bluntmachetti/aftershock/blob/main/docs/FIELD-NOTES.md"><code class="language-plaintext highlighter-rouge">docs/FIELD-NOTES.md</code></a>.</p>

<p>I’ll defend that as the <em>more</em> sophisticated use of the API, not the less. Shipping the fancy
feature by default because the rubric rewards fancy features is cargo-culting. Wiring it up,
measuring it against a real baseline on identical worlds, discovering it doesn’t pay for itself in
<em>your</em> regime, and making that an informed, reversible default — that’s engineering judgment.
“We used native function calling and measured exactly what it costs” is a stronger sentence than
“we used native function calling.”</p>

<h2 id="the-transferable-lesson-with-the-scope-caveat-that-matters">The transferable lesson (with the scope caveat that matters)</h2>

<p>The general rule: <strong>in a high-frequency multi-agent system, per-call overhead dominates — measure
it before you adopt it.</strong> Anything you attach to <em>every</em> request (tool schemas, verbose system
prompts, retrieved context, elaborate output formats) gets multiplied by your call count, and in a
society that number is large. The fancier API is not free; it’s free <em>per call</em> and you make
hundreds of calls.</p>

<p>And the caveat that keeps this honest: this is <strong>not</strong> “function calling is bad.” For a
single-agent assistant, or any app that makes a handful of calls per task, a 1,000-token schema is
a rounding error and the reliability and ergonomics of structured tool calls are well worth it —
the math flips entirely. Function calling earns its keep at low call counts. It just gets taxed to
death at high ones. Know which regime you’re in.</p>

<p>That’s the whole ethos of Aftershock in miniature: don’t ask whether the shiny thing <em>can</em> work —
measure when it <em>actually</em> pays, on worlds identical enough that the answer means something. This
time the shiny thing didn’t pay, and saying so out loud is the result.</p>

<p><strong>Try it live:</strong> <a href="https://aftershock.redoubtlabs.dev">https://aftershock.redoubtlabs.dev</a> · <strong>Read the code:</strong> <a href="https://github.com/bluntmachetti/aftershock">https://github.com/bluntmachetti/aftershock</a></p>

<p><em>Built with Qwen Cloud (<code class="language-plaintext highlighter-rouge">qwen3.5-flash</code> / <code class="language-plaintext highlighter-rouge">qwen3.5-plus</code> / <code class="language-plaintext highlighter-rouge">qwen3-max</code> via DashScope) and Alibaba
Cloud ECS, for the Qwen Cloud Global AI Hackathon.</em></p>]]></content><author><name>Kenny Ademolu</name></author><summary type="html"><![CDATA[An honest ablation: we added Qwen Cloud native function calling to the Aftershock agent society, benchmarked it on identical seeded worlds, and found it cost ~2× for no lives benefit. Why per-call tool-schema overhead dominates in high-frequency multi-agent systems — and why JSON contracts stayed the default.]]></summary></entry></feed>