<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yash Vardhan Shukla</title>
    <description>The latest articles on DEV Community by Yash Vardhan Shukla (@yash_vardhanshukla_82115).</description>
    <link>https://dev.to/yash_vardhanshukla_82115</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4060424%2Fa975b086-105e-454a-afaf-11b0c17aa763.png</url>
      <title>DEV Community: Yash Vardhan Shukla</title>
      <link>https://dev.to/yash_vardhanshukla_82115</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yash_vardhanshukla_82115"/>
    <language>en</language>
    <item>
      <title>The AI that hallucinated a bug into my zero dependency project</title>
      <dc:creator>Yash Vardhan Shukla</dc:creator>
      <pubDate>Mon, 31 Aug 2026 15:23:38 +0000</pubDate>
      <link>https://dev.to/yash_vardhanshukla_82115/the-ai-that-hallucinated-a-bug-into-my-zero-dependency-project-5dji</link>
      <guid>https://dev.to/yash_vardhanshukla_82115/the-ai-that-hallucinated-a-bug-into-my-zero-dependency-project-5dji</guid>
      <description>&lt;p&gt;Repo: &lt;a href="https://github.com/Yash-vs9/bindery" rel="noopener noreferrer"&gt;https://github.com/Yash-vs9/bindery&lt;/a&gt;&lt;br&gt;
Demo video: &lt;a href="https://youtu.be/9wFCPcWEZzM" rel="noopener noreferrer"&gt;https://youtu.be/9wFCPcWEZzM&lt;/a&gt;&lt;br&gt;
&lt;a class="mentioned-user" href="https://dev.to/partnerships_raptors"&gt;@partnerships_raptors&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;I built bindery for the Zero Dependency Hackathon: a tool that turns a folder&lt;br&gt;
of Markdown into a full documentation site, complete with live reload, full&lt;br&gt;
text search, PDF export, and hand rendered diagrams. One binary. Go standard&lt;br&gt;
library only. Empty manifest, no require block, nowhere for a dependency to&lt;br&gt;
even hide. The whole premise of this event is that half of today's code gets&lt;br&gt;
written by an AI that confidently invents package names that don't exist, and&lt;br&gt;
that the registry those hallucinated packages point at added something like&lt;br&gt;
four hundred and fifty thousand malicious entries last year alone. My plan&lt;br&gt;
was to prove the opposite was possible. Build something genuinely useful using&lt;br&gt;
only what the language already gives you, no imports, no excuses, and see how&lt;br&gt;
far that actually gets you.&lt;/p&gt;

&lt;p&gt;What I didn't expect was that the AI helping me build it would hallucinate&lt;br&gt;
something far more interesting than a fake package name. Over one long&lt;br&gt;
weekend it hallucinated a protocol constant, misread a standard library&lt;br&gt;
upgrade's silent behavior change, drew a graph with an arrow pointing at&lt;br&gt;
nothing, and then, near the very end, wrote a test that flagged its own&lt;br&gt;
correct code as a security hole. Every single one of those looked completely&lt;br&gt;
fine on the surface. Every single one compiled. Every single one passed the&lt;br&gt;
tests that existed at the time. Catching them, one at a time, ended up being&lt;br&gt;
the actual story of this project, more than the feature list ever was.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bug that would have failed silently forever
&lt;/h2&gt;

&lt;p&gt;Bindery's live reload works over a WebSocket I wrote by hand, because Go's&lt;br&gt;
standard library has no WebSocket implementation at all, none, not even an&lt;br&gt;
experimental one. The opening handshake needs one very specific ingredient: a&lt;br&gt;
GUID defined in RFC 6455, concatenated with the client's Sec WebSocket Key,&lt;br&gt;
hashed with SHA1, and base64 encoded into the response. Get one character of&lt;br&gt;
that GUID wrong and nothing crashes. No error. No stack trace. No panic to&lt;br&gt;
grep for in a log file. The socket just quietly, politely, never opens, and&lt;br&gt;
you sit there refreshing a browser that never reloads, with absolutely no clue&lt;br&gt;
why, because every layer above the handshake is working exactly as designed.&lt;/p&gt;

&lt;p&gt;That's exactly what happened. The AI wrote the GUID from memory and it was&lt;br&gt;
wrong. Not obviously wrong, not gibberish, not a string that looks like a&lt;br&gt;
placeholder. It had the right shape, the right length, the right hyphen&lt;br&gt;
pattern of a UUID, and it sat right next to a code comment claiming it was&lt;br&gt;
"transcribed directly from the RFC." It wasn't. One character had drifted&lt;br&gt;
from the front of the final group to the back of it, the kind of transposition&lt;br&gt;
a human proofreader skims straight past because the overall silhouette of the&lt;br&gt;
string looks correct.&lt;/p&gt;

&lt;p&gt;The only reason this got caught at all is that I refused to accept "it&lt;br&gt;
compiles" as evidence and insisted on a test that pinned the actual output&lt;br&gt;
against the worked example the RFC itself publishes, including the&lt;br&gt;
intermediate SHA1 digest, not just the final base64 string. That test failed&lt;br&gt;
on its very first run. And here's the part that actually worried me: when it&lt;br&gt;
failed, I went back to check the "correct" value from memory too, and my own&lt;br&gt;
recollection didn't match either. Neither the code nor my own head could be&lt;br&gt;
trusted at that moment, which meant there was exactly one thing left to do,&lt;br&gt;
which was go fetch the actual RFC text and check both of us against it like a&lt;br&gt;
referee. The code was wrong. My memory of what should replace it was also&lt;br&gt;
wrong in a different way. Only the primary source settled it.&lt;/p&gt;

&lt;p&gt;That felt like the entire hackathon compressed into one bug. An AI can write&lt;br&gt;
code fast and with total, unwavering confidence. It genuinely cannot tell you,&lt;br&gt;
from the inside, when that confidence is misplaced, because a hallucinated&lt;br&gt;
constant reads exactly the same as a correct one. The only real defense is a&lt;br&gt;
test that checks against ground truth published somewhere outside the model's&lt;br&gt;
own head, not a test that checks whether the output merely looks plausible.&lt;/p&gt;

&lt;h2&gt;
  
  
  When the standard library itself quietly broke me
&lt;/h2&gt;

&lt;p&gt;Go 1.27 shipped a new package, encoding/json/v2, and I reached for it to&lt;br&gt;
serialize bindery's search index because it's newer and faster and the&lt;br&gt;
hackathon's own capability notes flagged it as a fresh, real standard library&lt;br&gt;
answer worth using. What none of us caught until much later is that the old&lt;br&gt;
encoding/json sorted map keys before writing them out as JSON, quietly, as an&lt;br&gt;
implementation detail nobody ever had to think about, and the new package&lt;br&gt;
does not carry that behavior forward. It writes map keys in whatever order&lt;br&gt;
Go's runtime happens to iterate them internally, and Go deliberately&lt;br&gt;
randomizes that order between runs, on purpose, specifically so nobody&lt;br&gt;
accidentally depends on it.&lt;/p&gt;

&lt;p&gt;Bindery's search index is, structurally, a map of words to the list of pages&lt;br&gt;
containing them. So every single time I rebuilt the site, that JSON came out&lt;br&gt;
with its keys in a different byte order. Same words, same postings, same&lt;br&gt;
content in every meaningful sense, completely different bytes on disk. That&lt;br&gt;
kind of bug is invisible right up until the exact moment you try to prove&lt;br&gt;
something stronger than "it looks right," which is precisely what one of this&lt;br&gt;
event's bonus challenges asks for: build the same source twice, hash both&lt;br&gt;
outputs, and they had better match exactly.&lt;/p&gt;

&lt;p&gt;I wrote a test that built the identical search index nine times in a row and&lt;br&gt;
compared every byte of the result. It failed on the very first run. The&lt;br&gt;
compiled binary itself was perfectly reproducible, byte for byte, hash for&lt;br&gt;
hash. The data that binary produced when it actually ran was not. A check that&lt;br&gt;
only hashes the executable would have printed a clean green REPRODUCIBLE and&lt;br&gt;
sailed straight past a real, silent hole in the actual claim being made. The&lt;br&gt;
fix turned out to be a single line, a Deterministic option the new package&lt;br&gt;
happens to expose if you know to look for it, but finding the gap in the&lt;br&gt;
first place meant refusing to treat "reproducible" as a property of the build&lt;br&gt;
system alone, when it's really a property of every single piece of output&lt;br&gt;
that build system ever touches.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking at the actual picture instead of trusting the code
&lt;/h2&gt;

&lt;p&gt;Bindery renders diagrams straight out of Markdown fences, written in a small&lt;br&gt;
subset of Mermaid's syntax, but with zero JavaScript shipped to the browser&lt;br&gt;
and zero external layout library involved. It's a hand written graph layout&lt;br&gt;
algorithm underneath: assign every node a layer based on the longest path to&lt;br&gt;
it, order the nodes within each layer to reduce how many lines cross each&lt;br&gt;
other, then draw boxes and arrows as raw SVG text, no image library required&lt;br&gt;
anywhere in the chain.&lt;/p&gt;

&lt;p&gt;The first version compiled cleanly, passed every unit test I had written for&lt;br&gt;
it, and quietly produced a diagram where an arrow pointed directly at nothing,&lt;br&gt;
floating in empty space. A loop in the graph, something as mundane and common&lt;br&gt;
as "the file watcher notices a change, does its work, and goes back to&lt;br&gt;
waiting for the next one," completely broke the layering, because my layer&lt;br&gt;
assignment logic had quietly assumed the graph could never contain a cycle,&lt;br&gt;
and just kept pushing the same node deeper and deeper on every single pass&lt;br&gt;
whenever one actually existed.&lt;/p&gt;

&lt;p&gt;None of my tests caught this, for a very specific and slightly embarrassing&lt;br&gt;
reason: not one of them actually rendered the SVG and looked at it. They&lt;br&gt;
checked node counts. They checked edge counts. They checked that specific&lt;br&gt;
strings like "marker-end" showed up somewhere in the output. All of that&lt;br&gt;
passed while the picture itself was visibly, obviously broken to anyone who&lt;br&gt;
bothered to open it. I only found the bug because I exported that SVG to a&lt;br&gt;
PNG and actually looked at it, the exact same way any real human being would&lt;br&gt;
look at it before ever putting it in a demo video for other people to judge.&lt;br&gt;
And once I started actually looking instead of just asserting, I found a&lt;br&gt;
second problem sitting right next to the first one: an edge that spanned more&lt;br&gt;
than one layer was being drawn as a perfectly straight line directly through&lt;br&gt;
the boxes sitting between its two endpoints, which is completely correct&lt;br&gt;
coordinate math and completely wrong to look at.&lt;/p&gt;

&lt;p&gt;This is the pattern I kept running into over and over across this whole&lt;br&gt;
project. Correctness according to the tests I had already thought to write is&lt;br&gt;
not the same thing as correctness. Sometimes the only honest verification&lt;br&gt;
step is opening the actual output the way a real person eventually will.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three Windows bugs, and none of them were logic bugs
&lt;/h2&gt;

&lt;p&gt;Once the core parser was solid, I set up continuous integration across Linux,&lt;br&gt;
macOS, and Windows, because a judge running your submission on the wrong&lt;br&gt;
operating system and hitting a wall is entirely on you, not on them. Windows&lt;br&gt;
failed. Not once, but three separate times, on three genuinely different,&lt;br&gt;
completely unrelated causes, and looking back at all three together taught me&lt;br&gt;
something I didn't expect going in: every single one of them was a hidden&lt;br&gt;
assumption baked into a test, never a real defect in what bindery actually&lt;br&gt;
does.&lt;/p&gt;

&lt;p&gt;The first failure took down an entire suite of end to end tests all at once,&lt;br&gt;
every single one with the identical error, "executable file not found."&lt;br&gt;
Windows requires a literal dot exe extension to execute a binary at all, full&lt;br&gt;
stop, no exceptions, and my test harness built the shared test binary with a&lt;br&gt;
bare name and no extension whatsoever, because that's simply what works&lt;br&gt;
without a second thought on Linux and macOS. The fix was two lines checking&lt;br&gt;
the current operating system. The lesson underneath it was bigger: an entire&lt;br&gt;
category of failures, every single test in that file, traced back to one&lt;br&gt;
completely wrong assumption about what "runnable" even means on a different&lt;br&gt;
platform.&lt;/p&gt;

&lt;p&gt;The second failure was subtler and, honestly, more interesting to me. A test&lt;br&gt;
asserted that a missing directory produced the literal Unix error string "no&lt;br&gt;
such file or directory" on the program's stderr. Windows reports the&lt;br&gt;
identical underlying failure with entirely different wording, something like&lt;br&gt;
"the system cannot find the file specified," because that's simply how its&lt;br&gt;
own error reporting is worded at the operating system level. Bindery's actual&lt;br&gt;
behavior was completely correct on both platforms the entire time: right exit&lt;br&gt;
code, empty stdout, a real and useful error message on stderr. My test was&lt;br&gt;
quietly checking English phrasing rather than the actual behavior it claimed&lt;br&gt;
to be verifying.&lt;/p&gt;

&lt;p&gt;The third was the strangest of the three. Windows checks out Git repositories&lt;br&gt;
with a setting called autocrlf turned on by default, which silently rewrites&lt;br&gt;
every LF line ending to a CRLF pair inside anything Git considers a text&lt;br&gt;
file, including Go source files, including the exact multi line raw string&lt;br&gt;
literals my code embeds for the theme's CSS and JavaScript. Without an&lt;br&gt;
explicit gitattributes file forcing LF everywhere regardless of platform,&lt;br&gt;
those embedded byte for byte strings could have silently gained an invisible&lt;br&gt;
carriage return before every newline purely because of which operating system&lt;br&gt;
happened to check the repository out, an entirely different compiled binary&lt;br&gt;
built from an identical git commit depending solely on which machine cloned&lt;br&gt;
it.&lt;/p&gt;

&lt;p&gt;Three genuinely different root causes, three real fixes, and not one line of&lt;br&gt;
bindery's actual logic changed for any of them. What changed, every single&lt;br&gt;
time, was an assumption quietly baked into a test or a build script that&lt;br&gt;
nobody had ever bothered to question because it had simply never been wrong&lt;br&gt;
before that specific afternoon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sourcing real data instead of letting anything guess
&lt;/h2&gt;

&lt;p&gt;The PDF export needed accurate character widths so that lines of text&lt;br&gt;
actually wrap correctly instead of running off the edge of the page or&lt;br&gt;
leaving awkward gaps. The tempting shortcut here, the one I almost took, was&lt;br&gt;
to just ask for typical widths for a handful of common fonts and trust&lt;br&gt;
whatever number came back with total confidence. Given everything above, I&lt;br&gt;
didn't trust that shortcut for one second longer than it took to think of it.&lt;/p&gt;

&lt;p&gt;Instead I went and fetched the actual published Adobe Font Metrics files for&lt;br&gt;
Helvetica, Helvetica Bold, Helvetica Oblique, and Courier, the same core&lt;br&gt;
fourteen fonts every single PDF reader on the planet is contractually&lt;br&gt;
guaranteed to already have installed, parsed the real character width tables&lt;br&gt;
directly out of those files, and cross checked a handful of well known values&lt;br&gt;
by hand against numbers I could actually verify independently, like the fact&lt;br&gt;
that Helvetica's capital M is exactly eight hundred and thirty three&lt;br&gt;
thousandths of an em wide, and Courier is uniformly six hundred thousandths&lt;br&gt;
across every character because it's a monospace font by definition. A test&lt;br&gt;
now asserts both of those specific facts on every single run, which means a&lt;br&gt;
corrupted metrics table fails a build loudly instead of silently producing a&lt;br&gt;
subtly misaligned document that only a human proofreading a PDF would ever&lt;br&gt;
notice, months later.&lt;/p&gt;

&lt;p&gt;The exact same discipline showed up again chasing the very last percentage&lt;br&gt;
point of CommonMark conformance. Bindery sat at six hundred and fifty one out&lt;br&gt;
of six hundred and fifty two official spec examples for a while, one single&lt;br&gt;
stubborn failure away from a perfect score, and the one remaining case needed&lt;br&gt;
full Unicode case folding, specifically the capital sharp S character folding&lt;br&gt;
down to two lowercase letters rather than one. Go's standard library only&lt;br&gt;
implements simple case folding, one character to one character, by design,&lt;br&gt;
so there was no shortcut sitting there waiting to be called. I generated the&lt;br&gt;
actual exception table directly from the Unicode Consortium's own published&lt;br&gt;
CaseFolding.txt file, rather than trusting anyone's memory, mine or the&lt;br&gt;
model's, of which few dozen code points actually need special handling. That&lt;br&gt;
last one percent turned into a genuine, documented standard library gap&lt;br&gt;
instead of a fudged number, and bindery now passes all six hundred and fifty&lt;br&gt;
two.&lt;/p&gt;

&lt;h2&gt;
  
  
  Catching my own test lying to me
&lt;/h2&gt;

&lt;p&gt;Near the very end of the weekend, continuous integration's fuzz testing found&lt;br&gt;
an input that supposedly broke bindery's HTML escaping entirely: a raw HTML&lt;br&gt;
tag containing a literal angle bracket sitting inside one of its own&lt;br&gt;
attribute values. My own property based test flagged it immediately as a&lt;br&gt;
serious injection vulnerability, exactly the kind of finding that makes your&lt;br&gt;
stomach drop a little right before a submission deadline.&lt;/p&gt;

&lt;p&gt;Except it genuinely wasn't a vulnerability at all. CommonMark explicitly&lt;br&gt;
requires that raw HTML written directly by a document's own author pass&lt;br&gt;
straight through completely untouched, no escaping applied whatsoever,&lt;br&gt;
because that is precisely what "raw HTML support" means as a documented&lt;br&gt;
Markdown feature, and it's the identical behavior every other fully&lt;br&gt;
conformant Markdown renderer on earth exhibits, the same behavior already&lt;br&gt;
certified by that six fifty two out of six fifty two conformance number. My&lt;br&gt;
test was the thing that was wrong, not bindery's renderer. It had been&lt;br&gt;
scanning the entire rendered page for anything shaped even remotely like an&lt;br&gt;
HTML attribute, instead of checking only the small, specific handful of&lt;br&gt;
attributes bindery itself actually constructs from untrusted user input, like&lt;br&gt;
an href or a src.&lt;/p&gt;

&lt;p&gt;I did not simply loosen the check and quietly move on with my day, because a&lt;br&gt;
test you can no longer fully trust is meaningfully worse than having no test&lt;br&gt;
at all sitting there giving you false confidence. I deliberately, temporarily&lt;br&gt;
disabled the real escaping function on purpose, confirmed the newly narrowed&lt;br&gt;
test still correctly caught a genuinely leaked angle bracket when escaping&lt;br&gt;
was actually broken on purpose, and only then put the original code back and&lt;br&gt;
reran absolutely everything from scratch. Trusting the fix meant proving it&lt;br&gt;
both ways, not just one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What all of this actually proves
&lt;/h2&gt;

&lt;p&gt;None of the four bugs above were "the AI is simply bad at writing code." The&lt;br&gt;
code compiled cleanly every single time. It passed whatever tests already&lt;br&gt;
existed at that moment every single time. That is precisely what makes this&lt;br&gt;
particular failure mode so genuinely dangerous: confident, fluent,&lt;br&gt;
well formatted, plausible looking code that is subtly wrong in a way that&lt;br&gt;
looks, on the surface, exactly like code that is subtly right. A hallucinated&lt;br&gt;
constant does not announce itself. A silently changed default in a standard&lt;br&gt;
library upgrade does not announce itself. A layout algorithm that quietly&lt;br&gt;
assumes away cycles does not announce itself either, right up until you&lt;br&gt;
actually look.&lt;/p&gt;

&lt;p&gt;The fix was never simply "trust the AI less" as some vague, generalized&lt;br&gt;
posture. It was building layers of verification that check against something&lt;br&gt;
genuinely outside the code itself: an RFC's own published worked example, the&lt;br&gt;
same search index built nine separate times and compared byte for byte, an&lt;br&gt;
actual rendered picture opened and looked at with human eyes, a real escaping&lt;br&gt;
function deliberately broken on purpose and used as a canary, official&lt;br&gt;
published Unicode data pulled directly from its actual source rather than&lt;br&gt;
recalled from memory by anyone, human or otherwise. Every single one of those&lt;br&gt;
catches happened because I refused to accept "it compiles and the existing&lt;br&gt;
tests pass" as the actual finish line, and kept pushing one layer further&lt;br&gt;
each time.&lt;/p&gt;

&lt;p&gt;Bindery ends up at six hundred and fifty two out of six hundred and fifty two&lt;br&gt;
on the official CommonMark conformance suite, with a completely empty&lt;br&gt;
dependency manifest, and a reproducible build proven two entirely separate&lt;br&gt;
ways, the compiled binary and its actual data output both. But if I'm honest,&lt;br&gt;
the number I'm most genuinely proud of out of this whole weekend isn't six&lt;br&gt;
fifty two. It's four. Four real, distinct bugs, caught not because I somehow&lt;br&gt;
wrote flawless code on the first attempt, but because I built a project whose&lt;br&gt;
entire founding premise forced me to stop trusting anything I hadn't gone and&lt;br&gt;
independently verified myself, including the AI helping me, including my own&lt;br&gt;
memory, including the very tests I had written to protect myself from exactly&lt;br&gt;
this.&lt;/p&gt;

&lt;p&gt;That's the actual lesson sitting underneath a zero dependency hackathon, once&lt;br&gt;
you've lived inside one for a full weekend. It was never really about the&lt;br&gt;
packages. It was about learning, the hard way, four separate times in one&lt;br&gt;
weekend, what it actually costs you to trust something you never bothered to&lt;br&gt;
check.&lt;/p&gt;

&lt;p&gt;If you want to see any of this for yourself rather than just take my word for&lt;br&gt;
it, the full source is public at &lt;a href="https://github.com/Yash-vs9/bindery" rel="noopener noreferrer"&gt;https://github.com/Yash-vs9/bindery&lt;/a&gt;, and&lt;br&gt;
there's a five minute walkthrough of it actually running, live reload, search,&lt;br&gt;
the diagrams, the PDF export, and the reproducible build check all included,&lt;br&gt;
at &lt;a href="https://youtu.be/9wFCPcWEZzM" rel="noopener noreferrer"&gt;https://youtu.be/9wFCPcWEZzM&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>go</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>The test suite never knew it was running on Rust</title>
      <dc:creator>Yash Vardhan Shukla</dc:creator>
      <pubDate>Mon, 03 Aug 2026 10:39:55 +0000</pubDate>
      <link>https://dev.to/yash_vardhanshukla_82115/the-test-suite-never-knew-it-was-running-on-rust-1ljj</link>
      <guid>https://dev.to/yash_vardhanshukla_82115/the-test-suite-never-knew-it-was-running-on-rust-1ljj</guid>
      <description>&lt;p&gt;Port Mortem hands you seventy two hours and a dare. Take a real library written in one language, rebuild its guts in another, and prove the new version behaves exactly like the old one. The proof is where it gets interesting. You do not get to write cozy little tests that flatter your own code. You run the original project's own test files against your port, and you keep your hands off those files the entire time. If you touch them, you lose.&lt;/p&gt;

&lt;p&gt;I took Track D, Python to Rust, and I picked &lt;code&gt;grantjenks/python-sortedcontainers&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you have shipped Python for money you have almost certainly used it without thinking twice. It gives you a list that stays sorted as you add to it, a dict whose keys iterate in order, a set with order, and it does all of that in pure Python while keeping pace with things written in C. That last claim is the hook. There is no C extension hiding inside it. The speed comes from a data structure, not from escaping the language. I wanted to see what actually happens when you do escape the language.&lt;/p&gt;

&lt;h2&gt;
  
  
  The trick the library plays
&lt;/h2&gt;

&lt;p&gt;Most people reach for a balanced tree when they hear "keep it sorted." sortedcontainers does something dumber and faster. It keeps a list of smallish lists. New values get slotted into whichever sublist they belong in, and when a sublist grows past twice a load factor it splits in half. When one shrinks too far it merges with a neighbor. Each sublist stays short enough that a plain insert into a Python list, memory copy and all, beats the pointer chasing you would pay in a tree. This is square root decomposition, and it is the whole engine.&lt;/p&gt;

&lt;p&gt;The part that made me want to port it is positional indexing. &lt;code&gt;sl[5000]&lt;/code&gt; on a hundred thousand element sorted list has to find the five thousandth element in sorted order, fast. A &lt;code&gt;BTreeSet&lt;/code&gt; in Rust's standard library cannot do that. It has no idea how many elements sit to the left of any node. sortedcontainers builds a small binary tree of subtree sizes on the side, flattened into one flat array, and walks it in logarithmic time. That index is clever and finicky and exactly the kind of thing that breaks in quiet ways if you get the arithmetic slightly wrong.&lt;/p&gt;

&lt;p&gt;So I rebuilt it. One Rust crate, pure safe code, &lt;code&gt;#![forbid(unsafe_code)]&lt;/code&gt; at the top so the compiler physically refuses to let me cheat. The list of lists became a &lt;code&gt;Vec&amp;lt;Vec&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt;. The index tree became a &lt;code&gt;Vec&amp;lt;usize&amp;gt;&lt;/code&gt; with the same layout the original flattens into memory. There was one place the original computes an offset using &lt;code&gt;math.log&lt;/code&gt;, and floating point at exact powers of two is a coin flip you do not want in your addressing math, so I used integer bit tricks instead and got the same answer without ever touching a float.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making Python forget
&lt;/h2&gt;

&lt;p&gt;Here is the constraint that shapes everything. The tests do &lt;code&gt;import sortedcontainers&lt;/code&gt;. My module is a Rust extension called &lt;code&gt;sortedcontainers_rs&lt;/code&gt;. I am not allowed to edit a single test to fix that mismatch.&lt;/p&gt;

&lt;p&gt;The answer turned out to be small. A tiny shim directory named &lt;code&gt;sortedcontainers&lt;/code&gt; that re-exports my Rust classes, dropped onto the Python path ahead of everything else. When the test suite says &lt;code&gt;import sortedcontainers&lt;/code&gt;, Python finds my shim first, and the shim quietly hands back Rust. The test suite spends its entire run believing it is exercising the library it has always known. It never finds out. That is the part I keep grinning about. Two hundred and ninety six tests, written years ago by someone who had never heard of my project, all passing against code they were never meant to see.&lt;/p&gt;

&lt;h2&gt;
  
  
  The container that ate itself
&lt;/h2&gt;

&lt;p&gt;Every port has one bug that steals an evening. Mine was a test that builds a set, then adds the set to itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Python this is fine. The set now contains a reference to itself, and when you print it, the standard library notices the loop and prints an ellipsis instead of recursing forever. Cute. Harmless.&lt;/p&gt;

&lt;p&gt;In my Rust binding it detonated. &lt;code&gt;add&lt;/code&gt; had borrowed the set so it could mutate it. Then, to figure out where the new element belonged, it compared the element against the ones already inside, and the element was the set, so the comparison reached back in and tried to borrow the same set a second time. Rust's borrow rules do not care that this is clever. You cannot hand out a second borrow while a mutable one is live. The whole thing panicked with a message about a value already being mutably borrowed.&lt;/p&gt;

&lt;p&gt;The fix taught me something about writing bindings. The mistake was holding the borrow across a call back into Python. So I stopped doing that. &lt;code&gt;add&lt;/code&gt; now grabs what it needs, lets go of the set completely, lifts the ordered list out into a local variable, does the comparison heavy insertion there where nothing is borrowed, and only then puts everything back. The container can contain itself now, print its little ellipsis, and move on. Same fix pattern showed up three more times before I trusted it.&lt;/p&gt;

&lt;h2&gt;
  
  
  When a subclass has to arrive from nowhere
&lt;/h2&gt;

&lt;p&gt;The other one that cost me real time was quieter and nastier. There is a constructor detail in the original where &lt;code&gt;SortedList(key=something)&lt;/code&gt; does not give you a &lt;code&gt;SortedList&lt;/code&gt; at all. It hands back a &lt;code&gt;SortedKeyList&lt;/code&gt;, a different class, on the fly. A factory hiding inside a constructor.&lt;/p&gt;

&lt;p&gt;Rust bindings cannot do that directly. The moment Python decides which type it is building, that decision is made, and the binding does not get to swap the answer for a different class. I chased pure Rust solutions for a while and every one of them lied to the type system in a way that broke something else. In the end the honest place to put the dispatch was a thin Python layer, with the key list set up to inherit through a diamond so that every identity check the tests make still holds. &lt;code&gt;isinstance&lt;/code&gt; is happy, the exact type check is happy, and constructing it the wrong way still raises the same error the original raises. It is not the fix I wanted. It is the fix that is true.&lt;/p&gt;

&lt;h2&gt;
  
  
  The number I did not want to publish
&lt;/h2&gt;

&lt;p&gt;Everyone loves a benchmark where the new thing wins. I have those. Indexing into the sorted list is about four times faster in Rust, because it is pure integer tree walking with nothing crossing back into Python. Cold import is roughly ten times faster. Inserts are a little faster.&lt;/p&gt;

&lt;p&gt;Membership is slower. &lt;code&gt;x in sl&lt;/code&gt; runs about thirteen percent behind the pure Python version.&lt;/p&gt;

&lt;p&gt;I sat with that for a minute before deciding to lead with it rather than bury it. The reason is not mysterious once you see it. Every comparison during a membership check has to cross from Rust back into Python to ask two objects which one is smaller. Pure Python never leaves the interpreter, so it never pays that toll. My Rust core pays it on every single compare. The crossing is the cost. A tree or a fancier layout would not save me, because the bottleneck is the border, not the algorithm. So the number stays in the README, in bold, next to the wins. A benchmark you can trust is worth more than a benchmark that flatters you.&lt;/p&gt;

&lt;h2&gt;
  
  
  By the numbers
&lt;/h2&gt;

&lt;p&gt;Tests, the whole point of the exercise:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;296 of 296 passing.&lt;/strong&gt; Zero test files edited. Zero skipped. Zero marked as expected failures. The suite is provably byte for byte identical to the version pinned at kickoff.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fuzzing, our port against the real library, comparing results after every operation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;1,649,853 randomized operations&lt;/strong&gt; across list, set and dict. &lt;strong&gt;Zero divergences.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Speed, measured on a SortedList of 200,000 elements, CPython 3.13.1, p99 latency:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;operation&lt;/th&gt;
&lt;th&gt;original&lt;/th&gt;
&lt;th&gt;this port&lt;/th&gt;
&lt;th&gt;change&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;indexing &lt;code&gt;sl[i]&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;1583 ns&lt;/td&gt;
&lt;td&gt;375 ns&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4.2x faster&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;insert &lt;code&gt;add&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;1875 ns&lt;/td&gt;
&lt;td&gt;1417 ns&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1.3x faster&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;membership &lt;code&gt;x in sl&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;833 ns&lt;/td&gt;
&lt;td&gt;959 ns&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.87x, slower&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cold &lt;code&gt;import&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;7.38 ms&lt;/td&gt;
&lt;td&gt;0.75 ms&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9.8x faster&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The indexing win is even wider at the median than at the tail. Typical &lt;code&gt;sl[i]&lt;/code&gt; drops from around 1166 ns to 125 ns, close to nine times faster, because the whole operation is integer arithmetic in Rust and never once asks Python a question. Membership loses for the exact opposite reason. It cannot take a step without asking Python which of two objects is smaller, and every one of those questions is a trip across the border.&lt;/p&gt;

&lt;p&gt;Safety, the part the compiler guarantees rather than the part I promise:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Zero unsafe blocks&lt;/strong&gt; in the core. Not zero by discipline. Zero by &lt;code&gt;#![forbid(unsafe_code)]&lt;/code&gt;, which means the crate will not compile if I ever slip.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Hunting for a bug that was not there
&lt;/h2&gt;

&lt;p&gt;One of the bonus objectives is to find a real latent bug in the original library through differential testing. I wanted it badly. I built an oracle, a deliberately stupid and obviously correct model, a plain list kept sorted the slow honest way, and I threw millions of randomized operations at both it and the real library, comparing every result. I aimed at the corners where bugs like to hide. Inverted range bounds. Empty ranges. Negative step slices. Non monotonic keys and how ties order. Pickle round trips.&lt;/p&gt;

&lt;p&gt;It found nothing. The library is ten years old and it shows. Every single case came back clean.&lt;/p&gt;

&lt;p&gt;I thought about how to spin that into a finding anyway, some tiny documentation nitpick dressed up as a bug. Then I did not. Reporting a clean result honestly is the whole ethic of a project like this. A library surviving tens of millions of adversarial checks without a single divergence is a real result, and pretending otherwise would poison everything else I was claiming. So the write up says plainly: no bug found, and here is exactly how hard I looked.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proving I did not cheat
&lt;/h2&gt;

&lt;p&gt;The one accusation that could sink this project is "you edited the tests." So I made that accusation impossible to make. At the very start I took a cryptographic hash of every original test file and froze it. The submission carries a single kickoff hash that is bound to those exact files at those exact paths. Anyone can run one script and watch it confirm that the tests are byte for byte what they were on day one, and that they match the real upstream library at the pinned commit. Not similar. Identical.&lt;/p&gt;

&lt;p&gt;That hash turned into a small design constraint later, in a good way. When I was tempted to reshuffle folders to match a template more neatly, I realized moving the test directory would change the manifest, change its hash, and break the frozen pin. The provenance proof outranked the tidy folder. So the folder stayed where it was, and I wrote down why. Integrity you can verify beats structure that merely looks right.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually built
&lt;/h2&gt;

&lt;p&gt;Strip away the story and here is the residue. One safe Rust core, zero unsafe code, driving four containers through one shared element type. The original test suite passing in full, two hundred and ninety six out of two hundred and ninety six, with the files provably untouched. Millions of fuzzed operations with zero divergence from the real thing. Honest performance numbers including the one place I lose. And a decision log with seventeen entries explaining every place I chose to differ and why.&lt;/p&gt;

&lt;p&gt;The line I keep coming back to is the one Port Mortem opens with. Languages die and code does not. You can take an idea that someone poured years into, written in a language that will eventually fall out of fashion, and carry it forward into new ground without losing what made it correct. The proof that you carried it faithfully is not your word. It is the old code's own tests, running green against something they were never built for, none the wiser.&lt;/p&gt;

&lt;p&gt;Built for Port Mortem 2026, the 72 hour porting hackathon run by Hackathon Raptors (&lt;a class="mentioned-user" href="https://dev.to/partnerships_raptors"&gt;@partnerships_raptors&lt;/a&gt; ). The full project, the original test suite with its kickoff hash, the differential fuzzer, and the benchmark harness are all in the repo.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/Yash-vs9/Port_Mortem" rel="noopener noreferrer"&gt;https://github.com/Yash-vs9/Port_Mortem&lt;/a&gt;&lt;/p&gt;

</description>
      <category>hackathonraptors</category>
    </item>
  </channel>
</rss>
