PageSourceSearch

https://www.msreni.ai/tinyorbit/2026/10/03/tinyorbit.html

html msreni.ai collected 2026-10-05 15:23:30 UTC 60,252 bytes, 826 lines download raw bytes

1<!DOCTYPE html>
2<html>
3  <head>
4  <!-- Google tag (gtag.js) -->
vendor: 66 bytes, lines 4-5
4
5  <script async src="https://www.googletagmanager.com/gtag/js?id=
5G-02ZGVR2NEY
vendor: 14 bytes, lines 5-6
5"></script>
6  
6<script>
7    
vendor: 140 bytes, lines 7-11
7window.dataLayer = window.dataLayer || [];
8    function gtag(){dataLayer.push(arguments);}
9    gtag('js', new Date());
10
11    gtag('config', '
11G-02ZGVR2NEY
vendor: 6 bytes, lines 11-12
11');
12  
12</script>
12
13  <meta charset="utf-8">
14  <!-- (1) Optimize for mobile versions: http://goo.gl/EOpFl -->
15  <meta name="viewport" content="width=device-width, initial-scale=1.0">
16  <!-- (1) force latest IE rendering engine: bit.ly/1c8EiC9 -->
17  <meta http-equiv="X-UA-Compatible" content="IE=edge">
18
19  <title>TinyOrbit: An Agent Harness</title>
20  <meta name="description" content="  Estimated Reading Time: 9 minutes" />
21
22  <meta name="HandheldFriendly" content="True" />
23  <meta name="MobileOptimized" content="320" />
24  <meta name="apple-mobile-web-app-capable" content="yes">
25  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
26  
27    <meta name="twitter:card" content="summary" />
28    <meta name="twitter:site" content="@ms_ghotratweet" />
29    <meta name="twitter:title" content="TinyOrbit: An Agent Harness" />
30    <meta name="twitter:image" content="https://www.msreni.ai/assets/images/msreni.jpg" />
31    
32    <meta name="twitter:description"  content="  Estimated Reading Time: 9 minutes" />
33    
34  
35  
36  <meta property="og:site_name" content="The Tokens" />
37  <meta property="og:title" content="TinyOrbit: An Agent Harness"/>
38  
39  <meta property="og:description" content="  Estimated Reading Time: 9 minutes" />
40  
41  <meta property="og:image" content="https://www.msreni.ai/assets/images/msreni.jpg" />
42  <meta property="og:url" content="https://www.msreni.ai/tinyorbit/2026/10/03/tinyorbit.html" >
43  <meta property="og:type" content="blog" />
44  <meta property="article:published_time" content="2026-10-03T00:00:00+00:00">
45
46  <link rel="canonical" href="https://www.msreni.ai/tinyorbit/2026/10/03/tinyorbit.html"/>
47  <link rel="shortcut icon" href="/assets/images/ms_reni.png" type="image/png"/>
48  <link rel="stylesheet" href="//brick.a.ssl.fastly.net/Linux+Libertine:400,400i,700,700i/Open+Sans:400,400i,700,700i">
49  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Lora:ital,wght@1,500&display=swap">
50  <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
51
52  <link rel="stylesheet" type="text/css" media="screen" href="/css/main.css" />
53  <link rel="stylesheet" type="text/css" media="print" href="/css/print.css" />
54</head>
55
56  <body itemscope itemtype="http://schema.org/Article">
57    <!-- header start -->
58
59
60<!-- header end -->
61
62    <main class="content" role="main">
63      <article class="post">
64        
65        <div class="noarticleimage">
66          <div class="post-meta">
67            <h1 class="post-title">TinyOrbit: An Agent Harness <img class="title-logo" src="/assets/images/tinyorbit-logo.svg" alt=""></h1>
68            <div class="cf post-meta-text">
69              <div class="author-image" style="background-image: url(/assets/images/msreni.jpg)">Blog Logo</div>
70              <h4 class="author-name" itemprop="author" itemscope itemtype="http://schema.org/Person"></h4>
71              on
72              <time datetime="2026-10-03T00:00:00+00:00">03 Oct 2026</time>
73              <!-- , tagged on <span class="post-tag-">, <a href="/tag/"></a></span> -->
74            </div>
75          </div>
76        </div>
77        <br>
78        <br>
79        <br>
80        
81        <section class="post-content">
82          <div class="post-reading">
83            <span class="post-reading-time"></span> read
84          </div>
85          <a name="topofpage"></a>
86          <blockquote>
87  <p>Estimated Reading Time: <strong>9</strong> minutes</p>
88</blockquote>
89
90<p><em>TinyOrbit is the from-scratch agent harness at the heart of Chapter 6 of my book, <a href="https://www.amazon.com/dp/B0HKYGK476">Token by Token</a>. This is the short story of what it is, how it works, and what happened when I pointed it at real-world software bugs.</em></p>
91
92<hr />
93
94<h2 id="the-magic-trick-explained">The magic trick, explained</h2>
95
96<p>AI agents feel like magic. You type “fix this bug,” go make a hot chocolate, and come back to a patch. Surely there’s something enormous under the hood, a planning engine, a reasoning module, a small city of microservices?</p>
97
98<p>There’s a loop.</p>
99
100<p>That’s the secret. The model is the brain: it does the thinking. Everything around it is called a <strong>harness</strong>: the loop that keeps the conversation going, the tools the model is allowed to touch, and the safety rails that decide what it may touch. I wanted to prove how small that harness really is, to myself, and to the readers of my book, so I built one from scratch. It’s called <strong>TinyOrbit</strong>
100: a small pile of plain Python, one third-party dependency, no framework, small enough to read in an afternoon, which is more than I can say for my hot chocolate machine’s firmware.</p>
101
102<p><img src="/assets/images/tinyorbit-orbit.svg" alt="TinyOrbit: the model is the brain, the harness is the hands and legs, and TinyOrbit orbits around it all" style="width: 100%; height: auto;" /></p>
103
104<p>Look at the sketch. The head is the model, the brain. It reads the task, reasons about it, and decides what to do next. But a brain on its own can’t open a file or run a test. It can only think.</p>
105
106<p>Everything below the neck is the harness, and the closest thing to it in us is the limbic system: the old, unglamorous wiring that sits between thought and action. It carries the brain’s intent out to the hands, feeds back what the senses find, remembers what happened a moment ago, and flinches before you touch the hot stove. It isn’t clever, but without it the cleverest brain just sits there.</p>
107
108<p>Here’s how the two work together as an agent:</p>
109
110<ol>
111  <li><strong>Think.</strong> The model reads the conversation so far and picks a move: “read <code class="language-plaintext highlighter-rouge">models.py</code>,” or “run the tests.”</li>
112  <li><strong>Act.</strong> The harness carries that request to the hands, read, grep and glob in one, edit, write and bash in the other, and does exactly that, nothing more.</li>
113  <li><strong>Observe.</strong> Whatever comes back, file contents, test output, a stack trace, the harness hands straight back to the brain as new input.</li>
114  <li><strong>Repeat.</strong> Round and round, the orbit in TinyOrbit’s name, until the model answers without asking for a tool. That’s the loop saying “done.”</li>
115</ol>
116
117<p>Brain plus limbic system is a person who gets things done. Model plus harness is an agent. And that hatched belt around the waist? That’s the flinch: the permission gate that stops and asks before anything risky.</p>
118
119<p>Everything else is seatbelts.</p>
120
121<h2 id="the-seatbelts-are-the-interesting-part">The seatbelts are the interesting part</h2>
122
123<p>Here’s what building it taught me: the loop takes an hour. The <em>trust</em> takes the rest of your life.</p>
124
125<p>TinyOrbit’s tools are deliberately boring, read, write, edit, bash, glob, grep. The interesting engineering, the part that makes it a harness rather than a demo, is in what wraps them:</p>
126
127<ul>
128  <li><strong>Permissions, fail-closed.</strong> Reading files is free. Writing files or running shell commands? The agent stops and asks you first. An agent that can quietly run <code class="language-plaintext highlighter-rouge">rm -rf</code> is not an assistant, it’s a liability with good manners.</li>
129  <li><strong>Staleness detection.</strong> If the agent read a file, and you edited it behind its back, it refuses to blindly overwrite your changes. (A courtesy some humans have yet to master.)</li>
130  <li><strong>Interruption as a first-class citizen.</strong> Hit Ctrl+C mid-task and the agent doesn’t just die, it tidies up its half-finished tool calls so the conversation stays coherent. Every request the model makes gets an answer, even if that answer is “the human pulled the plug.”</li>
131  <li><strong>Memory files.</strong> Drop a <code class="language-plaintext highlighter-rouge">TINYORBIT.md</code> in your project with your conventions, and the agent reads it on startup, the difference between a contractor who read the brief and one who’s about to repaint your load-bearing wall.</li>
132</ul>
133
134<p>None of this is glamorous. All of it is the difference between a demo and a tool.</p>
135
136<h2 id="ok-but-does-it-actually-work">OK, but does it actually work?</h2>
137
138<p>Fair question. Vibes are not a benchmark, so I ran TinyOrbit (driving Claude Opus) against <strong>SWE-bench Verified</strong>, the industry-standard test where agents must fix real, historical bugs from real open-source projects, judged by the projects’ own test suites. No partial credit. The patch either passes or it doesn’t.</p>
139
140<p>On a random sample of ten tasks, TinyOrbit went <strong>10 for 10</strong>, for a grand total of $3.39 in API costs, less than the hot chocolate I drank while watching it work. On a deliberately cruel sample of ten <em>hard</em> tasks (the ones humans estimate at 1–4+ hours each), it went <strong>
1407 for 10</strong>. For context, when I scored the strongest published harnesses on those same hard ten, the best resolved 8.</p>
141
142<div class="harness-charts">
143<figure class="harness-fig">
144  <div class="harness-fig-title">Cost per task</div>
145  <div class="harness-fig-sub">Estimated from the token ledger at Opus 5 list prices. An outlined bar is an unresolved task.</div>
146  <div class="harness-fig-scroll"><svg viewBox="0 0 640 436" role="img" aria-label="Cost per task" font-family="Open Sans, Helvetica Neue, Arial, sans-serif">
147<line x1="150.0" x2="150.0" y1="26" y2="430" stroke="#e6e4de" />
148<text x="150.0" y="20.0" text-anchor="middle" font-size="10" fill="#999">$0.0</text>
149<line x1="240.0" x2="240.0" y1="26" y2="430" stroke="#e6e4de" />
150<text x="240.0" y="20.0" text-anchor="middle" font-size="10" fill="#999">$0.5</text>
151<line x1="330.0" x2="330.0" y1="26" y2="430" stroke="#e6e4de" />
152<text x="330.0" y="20.0" text-anchor="middle" font-size="10" fill="#999">$1.0</text>
153<line x1="420.0" x2="420.0" y1="26" y2="430" stroke="#e6e4de" />
154<text x="420.0" y="20.0" text-anchor="middle" font-size="10" fill="#999">$1.5</text>
155<line x1="510.0" x2="510.0" y1="26" y2="430" stroke="#e6e4de" />
156<text x="510.0" y="20.0" text-anchor="middle" font-size="10" fill="#999">$2.0</text>
157<text x="142.0" y="43.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">django-10554</text>
158<rect x="151.0" y="35" width="337.0" height="10" rx="3" fill="#fbfaf7" stroke="#eb6834" stroke-width="2"><title>django__django-10554 (1-4 hours)
159cost $1.88 · 56 calls · 11.2 min
160cache read 1,760,529 · out 26,398 tokens
161unresolved</title></rect>
162<text x="495.0" y="43.0" text-anchor="start" font-size="11" fill="#555">$1.88 · 56 calls · unresolved</text>
163<text x="142.0" y="63.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">sympy-13878</text>
164<rect x="150.0" y="54" width="318.9" height="12" rx="3" fill="#eb6834"><title>sympy__sympy-13878 (&gt;4 hours)
165cost $1.77 · 60 calls · 11.2 min
166cache read 1,751,833 · out 23,199 tokens
167resolved</title></rect>
168<text x="474.9" y="63.0" text-anchor="start" font-size="11" fill="#555">$1.77 · 60 calls</text>
169<text x="142.0" y="83.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">django-16560</text>
170<rect x="150.0" y="74" width="229.2" height="12" rx="3" fill="#eb6834"><title>django__django-16560 (1-4 hours)
171cost $1.27 · 50 calls · 3.7 min
172cache read 1,286,735 · out 13,988 tokens
173resolved</title></rect>
174<text x="385.2" y="83.0" text-anchor="start" font-size="11" fill="#555">$1.27 · 50 calls</text>
175<text x="142.0" y="103.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">pylint-4551</text>
176<rect x="150.0" y="94" width="205.3" height="12" rx="3" fill="#eb6834"><title>pylint-dev__pylint-4551 (1-4 hours)
177cost $1.14 · 41 calls · 4.5 min
178cache read 834,912 · out 19,699 tokens
179resolved</title></rect>
180<text x="361.3" y="103.0" text-anchor="start" font-size="11" fill="#555">$1.14 · 41 calls</text>
181<text x="142.0" y="123.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">astropy-13398</text>
182<rect x="151.0" y="115" width="186.6" height="10" rx="3" fill="#fbfaf7" stroke="#eb6834" stroke-width="2"><title>astropy__astropy-13398 (1-4 hours)
183cost $1.05 · 40 calls · 4.0 min
184cache read 892,836 · out 14,609 tokens
185unresolved</title></rect>
186<text x="344.6" y="123.0" text-anchor="start" font-size="11" fill="#555">$1.05 · 40 calls · unresolved</text>
187<text x="142.0" y="143.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">sympy-17630</text>
188<rect x="150.0" y="134" width="162.6" height="12" rx="3" fill="#eb6834"><title>sympy__sympy-17630 (1-4 hours)
189cost $0.90 · 45 calls · 6.1 min
190cache read 827,553 · out 12,197 tokens
191resolved</title></rect>
192<text x="318.6" y="143.0" text-anchor="start" font-size="11" fill="#555">$0.90 · 45 calls</text>
193<text x="142.0" y="163.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">sphinx-7590</text>
194<rect x="150.0" y="154" width="129.9" height="12" rx="3" fill="#eb6834"><title>sphinx-doc__sphinx-7590 (&gt;4 hours)
195cost $0.72 · 38 calls · 3.0 min
196cache read 574,011 · out 11,544 tokens
197resolved</title></rect>
198<text x="285.9" y="163.0" text-anchor="start" font-size="11" fill="#555">$0.72 · 38 calls</text>
199<text x="142.0" y="183.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">django-11885</text>
200<rect x="150.0" y="174" width="125.5" height="12" rx="3" fill="#eb6834"><title>django__django-11885 (1-4 hours)
201cost $0.70 · 30 calls · 5.8 min
202cache read 542,627 · out 10,438 tokens
203resolved</title></rect>
204<text x="281.5" y="183.0" text-anchor="start" font-size="11" fill="#555">$0.70 · 30 calls</text>
205<text x="142.0" y="203.0" text-anchor="end" font-size="11" fill="#555">django-15916</text>
206<rect x="150.0" y="194" width="115.1" height="12" rx="3" fill="#2a78d6"><title>django__django-15916 (15 min - 1 hour)
207cost $0.64 · 21 calls · 2.5 min
208cache read 424,028 · out 8,948 tokens
209resolved</title></rect>
210<text x="271.1" y="203.0" text-anchor="start" font-size="11" fill="#555">$0.64 · 21 calls</text>
211<text x="142.0" y="223.0" text-anchor="end" font-size="11" fill="#555">xarray-6938</text>
212<rect x="150.0" y="214" width="95.6" height="12" rx="3" fill="#2a78d6"><title>pydata__xarray-6938 (15 min - 1 hour)
213cost $0.53 · 31 calls · 13.7 min
214cache read 285,377 · out 6,644 tokens
215resolved</title></rect>
216<text x="251.6" y="223.0" text-anchor="start" font-size="11" fill="#555">$0.53 · 31 calls</text>
217<text x="142.0" y="243.0" text-anchor="end" font-size="11" fill="#555">django-12193</text>
218<rect x="150.0" y="234" width="86.9" height="12" rx="3" fill="#2a78d6"><title>django__django-12193 (&lt;15 min fix)
219cost $0.48 · 24 calls · 1.3 min
220cache read 453,145 · out 3,971 tokens
221resolved</title></rect>
222<text x="242.9" y="243.0" text-anchor="start" font-size="11" fill="#555">$0.48 · 24 calls</text>
223<text x="142.0" y="263.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">xarray-3993</text>
224<rect x="150.0" y="254" width="83.4" height="12" rx="3" fill="#eb6834"><title>pydata__xarray-3993 (1-4 hours)
225cost $0.46 · 30 calls · 2.0 min
226cache read 366,509 · out 6,753 tokens
227resolved</title></rect>
228<text x="239.4" y="263.0" text-anchor="start" font-size="11" fill="#555">$0.46 · 30 calls</text>
229<text x="142.0" y="283.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">pytest-10356</text>
230<rect x="151.0" y="275" width="57.7" height="10" rx="3" fill="#fbfaf7" stroke="#eb6834" stroke-width="2"><title>pytest-dev__pytest-10356 (1-4 hours)
231cost $0.33 · 22 calls · 1.8 min
232cache read 212,124 · out 5,381 tokens
233unresolved</title></rect>
234<text x="215.7" y="283.0" text-anchor="start" font-size="11" fill="#555">$0.33 · 22 calls · unresolved</text>
235<text x="142.0" y="303.0" text-anchor="end" font-size="11" fill="#555">sphinx-10449</text>
236<rect x="150.0" y="294" width="59.1" height="12" rx="3" fill="#2a78d6"><title>sphinx-doc__sphinx-10449 (&lt;15 min fix)
237cost $0.33 · 25 calls · 1.5 min
238cache read 242,369 · out 4,746 tokens
239resolved</title></rect>
240<text x="215.1" y="303.0" text-anchor="start" font-size="11" fill="#555">$0.33 · 25 calls</text>
241<text x="142.0" y="323.0" text-anchor="end" font-size="11" fill="#555">django-14493</text>
242<rect x="150.0" y="314" width="58.8" height="12" rx="3" fill="#2a78d6"><title>django__django-14493 (&lt;15 min fix)
243cost $0.33 · 19 calls · 1.2 min
244cache read 214,692 · out 2,921 tokens
245resolved</title></rect>
246<text x="214.8" y="323.0" text-anchor="start" font-size="11" fill="#555">$0.33 · 19 calls</text>
247<text x="142.0" y="343.0" text-anchor="end" font-size="11" fill="#555">django-11551</text>
248<rect x="150.0" y="334" width="50.7" height="12" rx="3" fill="#2a78d6"><title>django__django-11551 (15 min - 1 hour)
249cost $0.28 · 21 calls · 1.1 min
250cache read 180,306 · out 4,592 tokens
251resolved</title></rect>
252<text x="206.7" y="343.0" text-anchor="start" font-size="11" fill="#555">$0.28 · 21 calls</text>
253<text x="142.0" y="363.0" text-anchor="end" font-size="11" fill="#555">django-14672</text>
254<rect x="150.0" y="354" width="44.0" height="12" rx="3" fill="#2a78d6"><title>django__django-14672 (15 min - 1 hour)
255cost $0.24 · 22 calls · 1.0 min
256cache read 174,542 · out 3,352 tokens
257resolved</title></rect>
258<text x="200.0" y="363.0" text-anchor="start" font-size="11" fill="#555">$0.24 · 22 calls</text>
259<text x="142.0" y="383.0" text-anchor="end" font-size="11" fill="#555">pytest-5262</text>
260<rect x="150.0" y="374" width="37.8" height="12" rx="3" fill="#2a78d6"><title>pytest-dev__pytest-5262 (&lt;15 min fix)
261cost $0.21 · 20 calls · 1.0 min
262cache read 147,905 · out 3,042 tokens
263resolved</title></rect>
264<text x="193.8" y="383.0" text-anchor="start" font-size="11" fill="#555">$0.21 · 20 calls</text>
265<text x="142.0" y="403.0" text-anchor="end" font-size="11" fill="#555">django-11299</text>
266<rect x="150.0" y="394" width="33.6" height="12" rx="3" fill="#2a78d6"><title>django__django-11299 (&lt;15 min fix)
267cost $0.19 · 16 calls · 0.7 min
268cache read 118,755 · out 2,704 tokens
269resolved</title></rect>
270<text x="189.6" y="403.0" text-anchor="start" font-size="11" fill="#555">$0.19 · 16 calls</text>
271<text x="142.0" y="423.0" text-anchor="end" font-size="11" fill="#555">django-12143</text>
272<rect x="150.0" y="414" width="29.2" height="12" rx="3" fill="#2a78d6"><title>django__django-12143 (15 min - 1 hour)
273cost $0.16 · 19 calls · 1.0 min
274cache read 103,056 · out 2,732 tokens
275resolved</title></rect>
276<text x="185.2" y="423.0" text-anchor="start" font-size="11" fill="#555">$0.16 · 19 calls</text>
277<line x1="150.0" x2="150.0" y1="26" y2="430" stroke="#c9c6bd" />
278  </svg></div>
279  <div class="harness-legend"><span><i style="background:#2a78d6"></i>easy sample</span><span><i style="background:#eb6834"></i>hard sample</span></div>
280</figure>
281<figure class="harness-fig">
282  <div class="harness-fig-title">Turns and wall-clock per task</div>
283  <div class="harness-fig-sub">Left: API calls, capped at 60. Right: agent minutes in the container, inflated by x86 emulation on repos with slow test suites.</div>
284  <div class="harness-fig-scroll"><svg viewBox="0 0 640 450" role="img" aria-label="Turns and wall-clock per task" font-family="Open Sans, Helvetica Neue, Arial, sans-serif">
285<line x1="150.0" x2="150.0" y1="40" y2="444" stroke="#e6e4de" />
286<text x="150.0" y="34.0" text-anchor="middle" font-size="10" fill="#999">0</text>
287<line x1="213.3" x2="213.3" y1="40" y2="444" stroke="#e6e4de" />
288<text x="213.3" y="34.0" text-anchor="middle" font-size="10" fill="#999">20</text>
289<line x1="276.7" x2="276.7" y1="40" y2="444" stroke="#e6e4de" />
290<text x="276.7" y="34.0" text-anchor="middle" font-size="10" fill="#999">40</text>
291<line x1="340.0" x2="340.0" y1="40" y2="444" stroke="#e6e4de" />
292<text x="340.0" y="34.0" text-anchor="middle" font-size="10" fill="#999">60</text>
293<text x="150.0" y="22.0" text-anchor="start" font-size="10" fill="#999" font-weight="600">API CALLS</text>
294<text x="142.0" y="58.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">sympy-13878</text>
295<line x1="150.0" x2="340.0" y1="54" y2="54" stroke="#c9c6bd" />
296<circle cx="340.0" cy="54" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>sympy__sympy-13878
29760 calls · 11.2 min · exit max_turns
298resolved</title></circle>
299<text x="349.0" y="58.0" text-anchor="start" font-size="10" fill="#999">cap</text>
300<text x="142.0" y="78.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">django-10554</text>
301<line x1="150.0" x2="327.3" y1="74" y2="74" stroke="#c9c6bd" />
302<circle cx="327.3" cy="74" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>django__django-10554
30356 calls · 11.2 min · exit completed
304unresolved</title></circle>
305<text x="142.0" y="98.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">django-16560</text>
306<line x1="150.0" x2="308.3" y1="94" y2="94" stroke="#c9c6bd" />
307<circle cx="308.3" cy="94" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>django__django-16560
30850 calls · 3.7 min · exit completed
309resolved</title></circle>
310<text x="142.0" y="118.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">sympy-17630</text>
311<line x1="150.0" x2="292.5" y1="114" y2="114" stroke="#c9c6bd" />
312<circle cx="292.5" cy="114" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>sympy__sympy-17630
31345 calls · 6.1 min · exit completed
314resolved</title></circle>
315<text x="142.0" y="138.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">pylint-4551</text>
316<line x1="150.0" x2="279.8" y1="134" y2="134" stroke="#c9c6bd" />
317<circle cx="279.8" cy="134" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>pylint-dev__pylint-4551
31841 calls · 4.5 min · exit completed
319resolved</title></circle>
320<text x="142.0" y="158.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">astropy-13398</text>
321<line x1="150.0" x2="276.7" y1="154" y2="154" stroke="#c9c6bd" />
322<circle cx="276.7" cy="154" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>astropy__astropy-13398
32340 calls · 4.0 min · exit completed
324unresolved</title></circle>
325<text x="142.0" y="178.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">sphinx-7590</text>
326<line x1="150.0" x2="270.3" y1="174" y2="174" stroke="#c9c6bd" />
327<circle cx="270.3" cy="174" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>
327sphinx-doc__sphinx-7590
32838 calls · 3.0 min · exit completed
329resolved</title></circle>
330<text x="142.0" y="198.0" text-anchor="end" font-size="11" fill="#555">xarray-6938</text>
331<line x1="150.0" x2="248.2" y1="194" y2="194" stroke="#c9c6bd" />
332<circle cx="248.2" cy="194" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>pydata__xarray-6938
33331 calls · 13.7 min · exit completed
334resolved</title></circle>
335<text x="142.0" y="218.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">django-11885</text>
336<line x1="150.0" x2="245.0" y1="214" y2="214" stroke="#c9c6bd" />
337<circle cx="245.0" cy="214" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>django__django-11885
33830 calls · 5.8 min · exit completed
339resolved</title></circle>
340<text x="142.0" y="238.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">xarray-3993</text>
341<line x1="150.0" x2="245.0" y1="234" y2="234" stroke="#c9c6bd" />
342<circle cx="245.0" cy="234" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>pydata__xarray-3993
34330 calls · 2.0 min · exit completed
344resolved</title></circle>
345<text x="142.0" y="258.0" text-anchor="end" font-size="11" fill="#555">sphinx-10449</text>
346<line x1="150.0" x2="229.2" y1="254" y2="254" stroke="#c9c6bd" />
347<circle cx="229.2" cy="254" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>sphinx-doc__sphinx-10449
34825 calls · 1.5 min · exit completed
349resolved</title></circle>
350<text x="142.0" y="278.0" text-anchor="end" font-size="11" fill="#555">django-12193</text>
351<line x1="150.0" x2="226.0" y1="274" y2="274" stroke="#c9c6bd" />
352<circle cx="226.0" cy="274" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>django__django-12193
35324 calls · 1.3 min · exit completed
354resolved</title></circle>
355<text x="142.0" y="298.0" text-anchor="end" font-size="11" fill="#555">django-14672</text>
356<line x1="150.0" x2="219.7" y1="294" y2="294" stroke="#c9c6bd" />
357<circle cx="219.7" cy="294" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>django__django-14672
35822 calls · 1.0 min · exit completed
359resolved</title></circle>
360<text x="142.0" y="318.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">pytest-10356</text>
361<line x1="150.0" x2="219.7" y1="314" y2="314" stroke="#c9c6bd" />
362<circle cx="219.7" cy="314" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>pytest-dev__pytest-10356
36322 calls · 1.8 min · exit completed
364unresolved</title></circle>
365<text x="142.0" y="338.0" text-anchor="end" font-size="11" fill="#555">django-11551</text>
366<line x1="150.0" x2="216.5" y1="334" y2="334" stroke="#c9c6bd" />
367<circle cx="216.5" cy="334" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>django__django-11551
36821 calls · 1.1 min · exit completed
369resolved</title></circle>
370<text x="142.0" y="358.0" text-anchor="end" font-size="11" fill="#555">django-15916</text>
371<line x1="150.0" x2="216.5" y1="354" y2="354" stroke="#c9c6bd" />
372<circle cx="216.5" cy="354" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>django__django-15916
37321 calls · 2.5 min · exit completed
374resolved</title></circle>
375<text x="142.0" y="378.0" text-anchor="end" font-size="11" fill="#555">pytest-5262</text>
376<line x1="150.0" x2="213.3" y1="374" y2="374" stroke="#c9c6bd" />
377<circle cx="213.3" cy="374" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>pytest-dev__pytest-5262
37820 calls · 1.0 min · exit completed
379resolved</title></circle>
380<text x="142.0" y="398.0" text-anchor="end" font-size="11" fill="#555">django-14493</text>
381<line x1="150.0" x2="210.2" y1="394" y2="394" stroke="#c9c6bd" />
382<circle cx="210.2" cy="394" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>django__django-14493
38319 calls · 1.2 min · exit completed
384resolved</title></circle>
385<text x="142.0" y="418.0" text-anchor="end" font-size="11" fill="#555">django-12143</text>
386<line x1="150.0" x2="210.2" y1="414" y2="414" stroke="#c9c6bd" />
387<circle cx="210.2" cy="414" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>django__django-12143
38819 calls · 1.0 min · exit completed
389resolved</title></circle>
390<text x="142.0" y="438.0" text-anchor="end" font-size="11" fill="#555">django-11299</text>
391<line x1="150.0" x2="200.7" y1="434" y2="434" stroke="#c9c6bd" />
392<circle cx="200.7" cy="434" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>django__django-11299
39316 calls · 0.7 min · exit completed
394resolved</title></circle>
395<line x1="390.0" x2="390.0" y1="40" y2="444" stroke="#e6e4de" />
396<text x="390.0" y="34.0" text-anchor="middle" font-size="10" fill="#999">0</text>
397<line x1="453.3" x2="453.3" y1="40" y2="444" stroke="#e6e4de" />
398<text x="453.3" y="34.0" text-anchor="middle" font-size="10" fill="#999">5</text>
399<line x1="516.7" x2="516.7" y1="40" y2="444" stroke="#e6e4de" />
400<text x="516.7" y="34.0" text-anchor="middle" font-size="10" fill="#999">10</text>
401<line x1="580.0" x2="580.0" y1="40" y2="444" stroke="#e6e4de" />
402<text x="580.0" y="34.0" text-anchor="middle" font-size="10" fill="#999">15</text>
403<text x="390.0" y="22.0" text-anchor="start" font-size="10" fill="#999" font-weight="600">AGENT MINUTES</text>
404<line x1="390.0" x2="531.9" y1="54" y2="54" stroke="#c9c6bd" />
405<circle cx="531.9" cy="54" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>sympy__sympy-13878
40660 calls · 11.2 min · exit max_turns
407resolved</title></circle>
408<line x1="390.0" x2="531.9" y1="74" y2="74" stroke="#c9c6bd" />
409<circle cx="531.9" cy="74" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>django__django-10554
41056 calls · 11.2 min · exit completed
411unresolved</title></circle>
412<line x1="390.0" x2="436.9" y1="94" y2="94" stroke="#c9c6bd" />
413<circle cx="436.9" cy="94" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>django__django-16560
41450 calls · 3.7 min · exit completed
415resolved</title></circle>
416<line x1="390.0" x2="467.3" y1="114" y2="114" stroke="#c9c6bd" />
417<circle cx="467.3" cy="114" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>sympy__sympy-17630
41845 calls · 6.1 min · exit completed
419resolved</title></circle>
420<line x1="390.0" x2="447.0" y1="134" y2="134" stroke="#c9c6bd" />
421<circle cx="447.0" cy="134" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>pylint-dev__pylint-4551
42241 calls · 4.5 min · exit completed
423resolved</title></circle>
424<line x1="390.0" x2="440.7" y1="154" y2="154" stroke="#c9c6bd" />
425<circle cx="440.7" cy="154" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>astropy__astropy-13398
42640 calls · 4.0 min · exit completed
427unresolved</title></circle>
428<line x1="390.0" x2="428.0" y1="174" y2="174" stroke="#c9c6bd" />
429<circle cx="428.0" cy="174" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>sphinx-doc__sphinx-7590
43038 calls · 3.0 min · exit completed
431resolved</title></circle>
432<line x1="390.0" x2="563.5" y1="194" y2="194" stroke="#c9c6bd" />
433<circle cx="563.5" cy="194" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>pydata__xarray-6938
43431 calls · 13.7 min · exit completed
435resolved</title></circle>
436<line x1="390.0" x2="463.5" y1="214" y2="214" stroke="#c9c6bd" />
437<circle cx="463.5" cy="214" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>django__django-11885
43830 calls · 5.8 min · exit completed
439resolved</title></circle>
440<line x1="390.0" x2="415.3" y1="234" y2="234" stroke="#c9c6bd" />
441<circle cx="415.3" cy="234" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>pydata__xarray-3993
44230 calls · 2.0 min · exit completed
443resolved</title></circle>
444<line x1="390.0" x2="409.0" y1="254" y2="254" stroke="#c9c6bd" />
445<circle cx="409.0" cy="254" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>sphinx-doc__sphinx-10449
44625 calls · 1.5 min · exit completed
447resolved</title></circle>
448<line x1="390.0" x2="406.5" y1="274" y2="274" stroke="#c9c6bd" />
449<circle cx="406.5" cy="274" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>django__django-12193
45024 calls · 1.3 min · exit completed
451resolved</title></circle>
452<line x1="390.0" x2="402.7" y1="294" y2="294" stroke="#c9c6bd" />
453<circle cx="402.7" cy="294" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>django__django-14672
45422 calls · 1.0 min · exit completed
455resolved</title></circle>
456<line x1="390.0" x2="412.8" y1="314" y2="314" stroke="#c9c6bd" />
457<circle cx="412.8" cy="314" r="5" fill="#eb6834" stroke="#fbfaf7" stroke-width="2"><title>pytest-dev__pytest-10356
45822 calls · 1.8 min · exit completed
459unresolved</title></circle>
460<line x1="390.0" x2="403.9" y1="334" y2="334" stroke="#c9c6bd" />
461<circle cx="403.9" cy="334" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>django__django-11551
46221 calls · 1.1 min · exit completed
463resolved</title></circle>
464<line x1="390.0" x2="421.7" y1="354" y2="354" stroke="#c9c6bd" />
465<circle cx="421.7" cy="354" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>django__django-15916
46621 calls · 2.5 min · exit completed
467resolved</title></circle>
468<line x1="390.0" x2="402.7" y1="374" y2="374" stroke="#c9c6bd" />
469<circle cx="402.7" cy="374" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>pytest-dev__pytest-5262
47020 calls · 1.0 min · exit completed
471resolved</title></circle>
472<line x1="390.0" x2="405.2" y1="394" y2="394" stroke="#c9c6bd" />
473<circle cx="405.2" cy="394" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>django__django-14493
47419 calls · 1.2 min · exit completed
475resolved</title></circle>
476<line x1="390.0" x2="402.7" y1="414" y2="414" stroke="#c9c6bd" />
477<circle cx="402.7" cy="414" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>django__django-12143
47819 calls · 1.0 min · exit completed
479resolved</title></circle>
480<line x1="390.0" x2="398.9" y1="434" y2="434" stroke="#c9c6bd" />
481<circle cx="398.9" cy="434" r="5" fill="#2a78d6" stroke="#fbfaf7" stroke-width="2"><title>django__django-11299
48216 calls · 0.7 min · exit completed
483resolved</title></circle>
484  </svg></div>
485  <div class="harness-legend"><span><i style="background:#2a78d6"></i>easy</span><span><i style="background:#eb6834"></i>hard</span></div>
486</figure>
487<figure class="harness-fig">
488  <div class="harness-fig-title">Tool calls per task, by tool</div>
489  <div class="harness-fig-sub">Counted from the full message history. Bash dominates; Glob was never used in either run.</div>
490  <div class="harness-fig-scroll"><svg viewBox="0 0 640 436" role="img" aria-label="Tool calls per task, by tool" font-family="Open Sans, Helvetica Neue, Arial, sans-serif">
491<line x1="150.0" x2="150.0" y1="26" y2="430" stroke="#e6e4de" />
492<text x="150.0" y="20.0" text-anchor="middle" font-size="10" fill="#999">0</text>
493<line x1="264.3" x2="264.3" y1="26" y2="430" stroke="#e6e4de" />
494<text x="264.3" y="20.0" text-anchor="middle" font-size="10" fill="#999">20</text>
495<line x1="378.6" x2="378.6" y1="26" y2="430" stroke="#e6e4de" />
496<text x="378.6" y="20.0" text-anchor="middle" font-size="10" fill="#999">40</text>
497<line x1="492.9" x2="492.9" y1="26" y2="430" stroke="#e6e4de" />
498<text x="492.9" y="20.0" text-anchor="middle" font-size="10" fill="#999">60</text>
499<text x="142.0" y="43.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">sympy-13878</text>
500<rect x="150.5" y="34" width="204.7" height="12" rx="2" fill="#2a78d6"><title>sympy__sympy-13878: Bash 36 of 70 tool calls</title></rect>
501<text x="252.9" y="43.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 36</text>
502<rect x="356.2" y="34" width="90.4" height="12" rx="2" fill="#eb6834"><title>sympy__sympy-13878: Edit 16 of 70 tool calls</title></rect>
503<text x="401.4" y="43.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">16</text>
504<rect x="447.6" y="34" width="101.9" height="12" rx="2" fill="#1baf7a"><title>sympy__sympy-13878: Read 18 of 70 tool calls</title></rect>
505<text x="498.6" y="43.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">18</text>
506<text x="556.0" y="43.0" text-anchor="start" font-size="11" fill="#555">70</text>
507<text x="142.0" y="63.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">django-10554</text>
508<rect x="150.5" y="54" width="296.1" height="12" rx="2" fill="#2a78d6"><title>django__django-10554: Bash 52 of 55 tool calls</title></rect>
509<text x="298.6" y="63.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 52</text>
510<rect x="447.6" y="54" width="10.4" height="12" rx="2" fill="#eb6834"><title>django__django-10554: Edit 2 of 55 tool calls</title></rect>
511<rect x="459.1" y="54" width="4.7" height="12" rx="2" fill="#1baf7a"><title>django__django-10554: Read 1 of 55 tool calls</title></rect>
512<text x="470.3" y="63.0" text-anchor="start" font-size="11" fill="#555">55 · unresolved</text>
513<text x="142.0" y="83.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">django-16560</text>
514<rect x="150.5" y="74" width="107.6" height="12" rx="2" fill="#2a78d6"><title>django__django-16560: Bash 19 of 49 tool calls</title></rect>
515<text x="204.3" y="83.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 19</text>
516<rect x="259.1" y="74" width="130.4" height="12" rx="2" fill="#eb6834"><title>django__django-16560: Edit 23 of 49 tool calls</title></rect>
517<text x="324.3" y="83.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">23</text>
518<rect x="390.5" y="74" width="39.0" height="12" rx="2" fill="#1baf7a"><title>django__django-16560: Read 7 of 49 tool calls</title></rect>
519<text x="410.0" y="83.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">7</text>
520<text x="436.0" y="83.0" text-anchor="start" font-size="11" fill="#555">49</text>
521<text x="142.0" y="103.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">sympy-17630</text>
522<rect x="150.5" y="94" width="181.9" height="12" rx="2" fill="#2a78d6"><title>sympy__sympy-17630: Bash 32 of 44 tool calls</title></rect>
523<text x="241.4" y="103.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 32</text>
524<rect x="333.4" y="94" width="21.9" height="12" rx="2" fill="#eb6834"><title>sympy__sympy-17630: Edit 4 of 44 tool calls</title></rect>
525<rect x="356.2" y="94" width="44.7" height="12" rx="2" fill="#1baf7a"><title>sympy__sympy-17630: Read 8 of 44 tool calls</title></rect>
526<text x="378.6" y="103.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">8</text>
527<text x="407.4" y="103.0" text-anchor="start" font-size="11" fill="#555">44</text>
528<text x="142.0" y="123.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">pylint-4551</text>
529<rect x="150.5" y="114" width="119.0" height="12" rx="2" fill="#2a78d6"><title>pylint-dev__pylint-4551: Bash 21 of 41 tool calls</title></rect>
530<text x="210.0" y="123.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 21</text>
531<rect x="270.5" y="114" width="73.3" height="12" rx="2" fill="#eb6834"><title>pylint-dev__pylint-4551: Edit 13 of 41 tool calls</title></rect>
532<text x="307.1" y="123.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">13</text>
533<rect x="344.8" y="114" width="39.0" height="12" rx="2" fill="#1baf7a"><title>pylint-dev__pylint-4551: Read 7 of 41 tool calls</title></rect>
534<text x="364.3" y="123.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">7</text>
535<text x="390.3" y="123.0" text-anchor="start" font-size="11" fill="#555">41</text>
536<text x="142.0" y="143.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">astropy-13398</text>
537<rect x="150.5" y="134" width="159.0" height="12" rx="2" fill="#2a78d6"><title>astropy__astropy-13398: Bash 28 of 41 tool calls</title></rect>
538<text x="230.0" y="143.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 28</text>
539<rect x="310.5" y="134" width="33.3" height="12" rx="2" fill="#eb6834"><title>astropy__astropy-13398: Edit 6 of 41 tool calls</title></rect>
540<text x="327.1" y="143.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">6</text>
541<rect x="344.8" y="134" width="27.6" height="12" rx="2" fill="#1baf7a"><title>astropy__astropy-13398: Read 5 of 41 tool calls</title></rect>
542<rect x="373.4" y="134" width="10.4" height="12" rx="2" fill="#e87ba4"><title>astropy__astropy-13398: Write 2 of 41 tool calls</title></rect>
543<text x="390.3" y="143.0" text-anchor="start" font-size="11" fill="#555">41 · unresolved</text>
544<text x="142.0" y="163.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">sphinx-7590</text>
545<rect x="150.5" y="154" width="119.0" height="12" rx="2" fill="#2a78d6"><title>
545sphinx-doc__sphinx-7590: Bash 21 of 37 tool calls</title></rect>
546<text x="210.0" y="163.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 21</text>
547<rect x="270.5" y="154" width="61.9" height="12" rx="2" fill="#eb6834"><title>sphinx-doc__sphinx-7590: Edit 11 of 37 tool calls</title></rect>
548<text x="301.4" y="163.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">11</text>
549<rect x="333.4" y="154" width="27.6" height="12" rx="2" fill="#1baf7a"><title>sphinx-doc__sphinx-7590: Read 5 of 37 tool calls</title></rect>
550<text x="367.4" y="163.0" text-anchor="start" font-size="11" fill="#555">37</text>
551<text x="142.0" y="183.0" text-anchor="end" font-size="11" fill="#555">xarray-6938</text>
552<rect x="150.5" y="174" width="113.3" height="12" rx="2" fill="#2a78d6"><title>pydata__xarray-6938: Bash 20 of 30 tool calls</title></rect>
553<text x="207.1" y="183.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 20</text>
554<rect x="264.8" y="174" width="33.3" height="12" rx="2" fill="#eb6834"><title>pydata__xarray-6938: Edit 6 of 30 tool calls</title></rect>
555<text x="281.4" y="183.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">6</text>
556<rect x="299.1" y="174" width="16.1" height="12" rx="2" fill="#1baf7a"><title>pydata__xarray-6938: Read 3 of 30 tool calls</title></rect>
557<rect x="316.2" y="174" width="4.7" height="12" rx="2" fill="#eda100"><title>pydata__xarray-6938: Grep 1 of 30 tool calls</title></rect>
558<text x="327.4" y="183.0" text-anchor="start" font-size="11" fill="#555">30</text>
559<text x="142.0" y="203.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">django-11885</text>
560<rect x="150.5" y="194" width="101.9" height="12" rx="2" fill="#2a78d6"><title>django__django-11885: Bash 18 of 29 tool calls</title></rect>
561<text x="201.4" y="203.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 18</text>
562<rect x="253.4" y="194" width="44.7" height="12" rx="2" fill="#eb6834"><title>django__django-11885: Edit 8 of 29 tool calls</title></rect>
563<text x="275.7" y="203.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">8</text>
564<rect x="299.1" y="194" width="16.1" height="12" rx="2" fill="#1baf7a"><title>django__django-11885: Read 3 of 29 tool calls</title></rect>
565<text x="321.7" y="203.0" text-anchor="start" font-size="11" fill="#555">29</text>
566<text x="142.0" y="223.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">xarray-3993</text>
567<rect x="150.5" y="214" width="101.9" height="12" rx="2" fill="#2a78d6"><title>pydata__xarray-3993: Bash 18 of 31 tool calls</title></rect>
568<text x="201.4" y="223.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 18</text>
569<rect x="253.4" y="214" width="44.7" height="12" rx="2" fill="#eb6834"><title>pydata__xarray-3993: Edit 8 of 31 tool calls</title></rect>
570<text x="275.7" y="223.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">8</text>
571<rect x="299.1" y="214" width="27.6" height="12" rx="2" fill="#1baf7a"><title>pydata__xarray-3993: Read 5 of 31 tool calls</title></rect>
572<text x="333.1" y="223.0" text-anchor="start" font-size="11" fill="#555">31</text>
573<text x="142.0" y="243.0" text-anchor="end" font-size="11" fill="#555">sphinx-10449</text>
574<rect x="150.5" y="234" width="90.4" height="12" rx="2" fill="#2a78d6"><title>sphinx-doc__sphinx-10449: Bash 16 of 24 tool calls</title></rect>
575<text x="195.7" y="243.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 16</text>
576<rect x="241.9" y="234" width="33.3" height="12" rx="2" fill="#eb6834"><title>sphinx-doc__sphinx-10449: Edit 6 of 24 tool calls</title></rect>
577<text x="258.6" y="243.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">6</text>
578<rect x="276.2" y="234" width="10.4" height="12" rx="2" fill="#1baf7a"><title>sphinx-doc__sphinx-10449: Read 2 of 24 tool calls</title></rect>
579<text x="293.1" y="243.0" text-anchor="start" font-size="11" fill="#555">24</text>
580<text x="142.0" y="263.0" text-anchor="end" font-size="11" fill="#555">django-12193</text>
581<rect x="150.5" y="254" width="101.9" height="12" rx="2" fill="#2a78d6"><title>django__django-12193: Bash 18 of 23 tool calls</title></rect>
582<text x="201.4" y="263.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 18</text>
583<rect x="253.4" y="254" width="10.4" height="12" rx="2" fill="#eb6834"><title>django__django-12193: Edit 2 of 23 tool calls</title></rect>
584<rect x="264.8" y="254" width="16.1" height="12" rx="2" fill="#1baf7a"><title>django__django-12193: Read 3 of 23 tool calls</title></rect>
585<text x="287.4" y="263.0" text-anchor="start" font-size="11" fill="#555">23</text>
586<text x="142.0" y="283.0" text-anchor="end" font-size="11" fill="#555">django-14672</text>
587<rect x="150.5" y="274" width="90.4" height="12" rx="2" fill="#2a78d6"><title>django__django-14672: Bash 16 of 21 tool calls</title></rect>
588<text x="195.7" y="283.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 16</text>
589<rect x="241.9" y="274" width="16.1" height="12" rx="2" fill="#eb6834"><title>django__django-14672: Edit 3 of 21 tool calls</title></rect>
590<rect x="259.1" y="274" width="10.4" height="12" rx="2" fill="#1baf7a"><title>django__django-14672: Read 2 of 21 tool calls</title></rect>
591<text x="276.0" y="283.0" text-anchor="start" font-size="11" fill="#555">21</text>
592<text x="142.0" y="303.0" text-anchor="end" font-size="11" fill="#555" font-weight="600">pytest-10356</text>
593<rect x="150.5" y="294" width="73.3" height="12" rx="2" fill="#2a78d6"><title>pytest-dev__pytest-10356: Bash 13 of 21 tool calls</title></rect>
594<text x="187.1" y="303.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 13</text>
595<rect x="224.8" y="294" width="27.6" height="12" rx="2" fill="#eb6834"><title>pytest-dev__pytest-10356: Edit 5 of 21 tool calls</title></rect>
596<rect x="253.4" y="294" width="10.4" height="12" rx="2" fill="#1baf7a"><title>pytest-dev__pytest-10356: Read 2 of 21 tool calls</title></rect>
597<rect x="264.8" y="294" width="4.7" height="12" rx="2" fill="#e87ba4"><title>pytest-dev__pytest-10356: Write 1 of 21 tool calls</title></rect>
598<text x="276.0" y="303.0" text-anchor="start" font-size="11" fill="#555">21 · unresolved</text>
599<text x="142.0" y="323.0" text-anchor="end" font-size="11" fill="#555">django-11551</text>
600<rect x="150.5" y="314" width="73.3" height="12" rx="2" fill="#2a78d6"><title>django__django-11551: Bash 13 of 20 tool calls</title></rect>
601<text x="187.1" y="323.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 13</text>
602<rect x="224.8" y="314" width="27.6" height="12" rx="2" fill="#eb6834"><title>django__django-11551: Edit 5 of 20 tool calls</title></rect>
603<rect x="253.4" y="314" width="10.4" height="12" rx="2" fill="#1baf7a"><title>django__django-11551: Read 2 of 20 tool calls</title></rect>
604<text x="270.3" y="323.0" text-anchor="start" font-size="11" fill="#555">20</text>
605<text x="142.0" y="343.0" text-anchor="end" font-size="11" fill="#555">django-15916</text>
606<rect x="150.5" y="334" width="56.1" height="12" rx="2" fill="#2a78d6"><title>django__django-15916: Bash 10 of 23 tool calls</title></rect>
607<text x="178.6" y="343.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 10</text>
608<rect x="207.6" y="334" width="21.9" height="12" rx="2" fill="#eb6834"><title>django__django-15916: Edit 4 of 23 tool calls</title></rect>
609<rect x="230.5" y="334" width="33.3" height="12" rx="2" fill="#1baf7a"><title>django__django-15916: Read 6 of 23 tool calls</title></rect>
610<text x="247.1" y="343.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">6</text>
611<rect x="264.8" y="334" width="16.1" height="12" rx="2" fill="#eda100"><title>django__django-15916: Grep 3 of 23 tool calls</title></rect>
612<text x="287.4" y="343.0" text-anchor="start" font-size="11" fill="#555">23</text>
613<text x="142.0" y="363.0" text-anchor="end" font-size="11" fill="#555">pytest-5262</text>
614<rect x="150.5" y="354" width="56.1" height="12" rx="2" fill="#2a78d6"><title>pytest-dev__pytest-5262: Bash 10 of 20 tool calls</title></rect>
615<text x="178.6" y="363.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 10</text>
616<rect x="207.6" y="354" width="21.9" height="12" rx="2" fill="#eb6834"><title>pytest-dev__pytest-5262: Edit 4 of 20 tool calls</title></rect>
617<rect x="230.5" y="354" width="10.4" height="12" rx="2" fill="#1baf7a"><title>pytest-dev__pytest-5262: Read 2 of 20 tool calls</title></rect>
618<rect x="241.9" y="354" width="16.1" height="12" rx="2" fill="#eda100"><title>pytest-dev__pytest-5262: Grep 3 of 20 tool calls</title></rect>
619<rect x="259.1" y="354" width="4.7" height="12" rx="2" fill="#e87ba4"><title>pytest-dev__pytest-5262: Write 1 of 20 tool calls</title></rect>
620<text x="270.3" y="363.0" text-anchor="start" font-size="11" fill="#555">20</text>
621<text x="142.0" y="383.0" text-anchor="end" font-size="11" fill="#555">django-14493</text>
622<rect x="150.5" y="374" width="44.7" height="12" rx="2" fill="#2a78d6"><title>django__django-14493: Bash 8 of 18 tool calls</title></rect>
623<text x="172.9" y="383.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 8</text>
624<rect x="196.2" y="374" width="16.1" height="12" rx="2" fill="#eb6834"><title>django__django-14493: Edit 3 of 18 tool calls</title></rect>
625<rect x="213.4" y="374" width="21.9" height="12" rx="2" fill="#1baf7a"><title>django__django-14493: Read 4 of 18 tool calls</title></rect>
626<rect x="236.2" y="374" width="16.1" height="12" rx="2" fill="#eda100"><title>django__django-14493: Grep 3 of 18 tool calls</title></rect>
627<text x="258.9" y="383.0" text-anchor="start" font-size="11" fill="#555">18</text>
628<text x="142.0" y="403.0" text-anchor="end" font-size="11" fill="#555">django-12143</text>
629<rect x="150.5" y="394" width="67.6" height="12" rx="2" fill="#2a78d6"><title>django__django-12143: Bash 12 of 18 tool calls</title></rect>
630<text x="184.3" y="403.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 12</text>
631<rect x="219.1" y="394" width="10.4" height="12" rx="2" fill="#eb6834"><title>django__django-12143: Edit 2 of 18 tool calls</title></rect>
632<rect x="230.5" y="394" width="10.4" height="12" rx="2" fill="#1baf7a"><title>django__django-12143: Read 2 of 18 tool calls</title></rect>
633<rect x="241.9" y="394" width="10.4" height="12" rx="2" fill="#eda100"><title>django__django-12143: Grep 2 of 18 tool calls</title></rect>
634<text x="258.9" y="403.0" text-anchor="start" font-size="11" fill="#555">18</text>
635<text x="142.0" y="423.0" text-anchor="end" font-size="11" fill="#555">django-11299</text>
636<rect x="150.5" y="414" width="44.7" height="12" rx="2" fill="#2a78d6"><title>django__django-11299: Bash 8 of 15 tool calls</title></rect>
637<text x="172.9" y="423.0" text-anchor="middle" font-size="9.5" fill="#fff" font-weight="600">Bash 8</text>
638<rect x="196.2" y="414" width="27.6" height="12" rx="2" fill="#eb6834"><title>django__django-11299: Edit 5 of 15 tool calls</title></rect>
639<rect x="224.8" y="414" width="10.4" height="12" rx="2" fill="#1baf7a"><title>django__django-11299: Read 2 of 15 tool calls</title></rect>
640<text x="241.7" y="423.0" text-anchor="start" font-size="11" fill="#555">15</text>
641  </svg></div>
642  <div class="harness-legend"><span><i style="background:#2a78d6"></i>Bash</span><span><i style="background:#eb6834"></i>Edit</span><span><i style="background:#1baf7a"></i>Read</span><span><i style="background:#eda100"></i>Grep</span><span><i style="background:#e87ba4"></i>Write</span></div>
643</figure>
644</div>
645
646<p>Before anyone prints a trophy: ten tasks is a small sample, the model deserves a large share of the credit, and the comparison isn’t apples-to-apples since published entries ran older models. The honest reading is <em>model-plus-harness</em>, not “my weekend project beats the industry.”</p>
647
648<p>And the three misses? All three failed the same way, and it’s deliciously human: the agent wrote its own tests, passed its own tests, and confidently declared victory, without ever reproducing the actual bug first. It graded its own homework. Every engineer I’ve told this to has gone quiet for a second, because we’ve all met that developer. Some of us in the mirror.</p>
649
650<h2 id="why-this-matters-and-where-the-book-comes-in">Why this matters (and where the book comes in)</h2>
651
652<p>The lesson of TinyOrbit isn’t “look how clever.” It’s the opposite: <strong>this technology is understandable.</strong> The agent loop that powers the billion-dollar tools is something you can read, build, and own in an afternoon. Once you’ve seen it, AI agents stop being magic and start being engineering, and you can reason about when to trust them, where they’ll fail, and what the seatbelts should be.</p>
653
654<p>That’s the whole philosophy of <em>Token by Token</em>: the best way to understand AI is to build it. Chapter 6 walks through the agent loop step by step, TinyOrbit for the full harness, plus two small agents that debate each other live, with hand-drawn diagrams and runnable code for every idea. Earlier chapters build everything underneath it: a neural network from a single neuron, an autograd engine from high-school calculus, GPT-2 from scratch, and a model that learns to reason.</p>
655
656<p><strong>The code:</strong> <a href="https://github.com/badlogicmanpreet/tinyorbit">github.com/badlogicmanpreet/tinyorbit</a>, including the full SWE-bench reports with every verdict and a wire-level trace of one task, stream event by stream event.</p>
657
658<p><strong>The book:</strong> <a href="https://www.amazon.com/dp/B0HKYGK476">Token by Token: A Journey Through AI, Mathematics, and Machine Intelligence</a>, available on Amazon (<a href="https://www.amazon.co.uk/dp/B0HKYGK476">UK</a> · <a href="https://www.amazon.in/dp/B0HLQ9BR81">India</a>), <a href="https://www.amazon.com/dp/B0HL56R3K6">Kindle</a>, and <a href="https://notionpress.com/in/read/token-by-token/paperback">Notion Press</a>.</p>
659
660<p>Build one. It’s the fastest way to stop believing in magic, and start doing it.</p>
661
662        </section>
663        <button id="like-button" class="like-button">
664          <span class="icon">❤️</span>
665          <span class="count" id="like-count">0</span>
666        </button>              
667        <!--<footer class="post-footer">
668          <section class="share">
669            
670              
671            
672              
673                <a class="icon-linkedin" href="http://linkedin.com/share?text=TinyOrbit%3A+An+Agent+Harness&amp;url=https://www.msreni.ai/tinyorbit/2026/10/03/tinyorbit"
674                  onclick="window.open(this.href, 'linkedin-share', 'width=550,height=255');return false;">
675                <i class="fa fa-linkedin"></i><span class="hidden">linkedin</span>
676                </a>
677              
678            
679              
680            
681          </section>
682        </footer> -->
683        <div class="bottom-teaser cf">
684          <div class="isLeft">
685            <h5 class="index-headline featured"><span>Written by</span></h5>
686            <section class="author">
687              <div class="author-image" style="background-image: url(/assets/images/msreni.jpg)">Blog Logo</div>
688              <h4>Manpreet & Renaira</h4>
689              <p class="bio"></p>
690              <hr>
691              <p class="published">Published <time datetime="2026-10-03 00:00">03 Oct 2026</time></p>
692            </section>
693          </div>
694          
695          <div class="isRight">
696            <h5 class="index-headline featured"><span>Supported by</span></h5>
697            <footer class="site-footer">
698              <section class="poweredby">Believe you can and you're halfway there!<a href="http://jekyllrb.com"></a></section>
699              <a class="subscribe" href="mailto:[email protected]""> <span class="tooltip"> <i class="fa fa-rss"></i> Contact Me.</span></a>
700              <div class="inner">
701                <section class="copyright">All content copyright <a href="mailto:[email protected]">Manpreet & Renaira</a> &copy; 2026<br>All rights reserved.</section>
702              </div>
703            </footer>
704          </div>
705        </div>
706        
707      </article>
708    </main>
709    <div class="bottom-closer">
710      <div class="background-closer-image"  style="background-image: url(/assets/images/background_image.jpg)">
711        Image
712      </div>
713      <div class="inner">
714        <h1 class="blog-title">The Tokens</h1>
715        <h2 class="blog-description"><strong class="tagline">Bonding through words, and the math behind them.</strong><br>Manpreet & Renaira</h2>
716        <a href=/ class="btn">Back to Overview</a>
717      </div>
718    </div>
719    
719<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
vendor: 1 bytes, line 719
719
720<script type="text/javascript" src="/assets/js/jquery.fitvids.js"></script>
vendor: 1 bytes, line 720
720
721<script type="text/javascript" src="/assets/js/index.js"></script>
vendor: 1 bytes, line 721
721
722<script type="text/javascript" src="/assets/js/readingTime.min.js"></script>
vendor: 1 bytes, line 722
722
723<script>
724(function ($) {
725  "use strict";
726  $(document).ready(function(){
727
728    var $window = $(window),
729    $image = $('.post-image-image, .teaserimage-image');
730    
731      $window.on('scroll', function() {
732        var top = $window.scrollTop();
733
734        if (top < 0 || top > 1500) { return; }
735        $image
736          .css('transform', 'translate3d(0px, '+top/3+'px, 0px)')
737          .css('opacity', 1-Math.max(top/700, 0));
738      });
739      $window.trigger('scroll');
740
741      var height = $('.article-image').height();
742      $('.post-content').css('padding-top', height + 'px');
743
744      $('a[href*=#]:not([href=#])').click(function() {
745        if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'')
746         && location.hostname == this.hostname) {
747          var target = $(this.hash);
748          target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
749          if (target.length) {
750            $('html,body').animate({ scrollTop: target.offset().top }, 500);
751            return false;
752          }
753        }
754      });
755
756  });
757}(jQuery));
758</script>
758
759
760
761    
761<script type="module">
762      // Import the functions you need from the SDKs you need
763      import { initializeApp } from "https://www.gstatic.com/firebasejs/11.0.2/firebase-app.js";
764      import { getFirestore, doc, getDoc, setDoc, collection, runTransaction} from "https://www.gstatic.com/firebasejs/11.0.2/firebase-firestore.js";
765      import { getAnalytics } from "https://www.gstatic.com/firebasejs/11.0.2/firebase-analytics.js";
766      // TODO: Add SDKs for Firebase products that you want to use
767      // https://firebase.google.com/docs/web/setup#available-libraries
768
769      // Your web app's Firebase configuration
770      // For Firebase JS SDK v7.20.0 and later, measurementId is optional
771      // Encoded Firebase configuration
772      const encodedConfig = {
773        apiKey: "QUl6YVN5QUxZdExMeTNieVlMV18=", // Encoded value
774        authDomain: "YWVyb3NvZnQtYmU0NDguZmlyZWJhc2VhcHAuY29t",
775        projectId: "YWVyb3NvZnQtYmU0NDg=",
776        storageBucket: "YWVyb3NvZnQtYmU0NDguZmlyZWJhc2VzdG9yYWdlLmFwcA==",
777        messagingSenderId: "ODUwOTc5MzgyMDIx",
778        appId: "MToxODUwOTc5MzgyMDIxOndlYjpkZjg5MThhYjUzMThlNzUxNDU4ZDZj",
779        measurementId: "Ry0yMDJFWVJZUFQx"
780      };
781
782      // Decode the configuration dynamically
783      const firebaseConfig = {
784        apiKey: atob(encodedConfig.apiKey),
785        authDomain: atob(encodedConfig.authDomain),
786        projectId: atob(encodedConfig.projectId),
787        storageBucket: atob(encodedConfig.storageBucket),
788        messagingSenderId: atob(encodedConfig.messagingSenderId),
789        appId: atob(encodedConfig.appId),
790        measurementId: atob(encodedConfig.measurementId),
791      };
792      // Initialize Firebase
793      const app = initializeApp(firebaseConfig);
794      const db = getFirestore(app);
795
796      // Fetch likes
797      async function fetchLikes(postId) {
798        const docRef = doc(db, "likes", postId);
799        const docSnap = await getDoc(docRef);
800        if (docSnap.exists()) {
801          document.getElementById('like-count').textContent = docSnap.data().count || 0;
802        } else {
803          document.getElementById('like-count').textContent = 0;
804        }
805      }
806
807      // Increment likes
808      async function addLike(postId) {
809        const docRef = doc(db, "likes", postId);
810        await runTransaction(db, async (transaction) => {
811          const docSnap = await transaction.get(docRef);
812          const newCount = (docSnap.exists() ? docSnap.data().count : 0) + 1;
813          transaction.set(docRef, { count: newCount });
814        });
815        fetchLikes(postId);
816      }
817
818      // Set up the like button
819      const postId = "tinyorbit-2026-10-03-tinyorbit-html"; // Unique ID for the post
820      document.getElementById('like-button').addEventListener('click', () => addLike(postId));
821      fetchLikes(postId); // Load likes on page load
822
823    </script>
823
824
825  </body>
826</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.