
I’ve been thinking about vibe coding, the guardrails, the evals that we have to build, and the occasional scorn in various forums from experts who write every line themselves. It takes me back to my android obsession days when flashing ROMs onto phones was a thing (vibe flashing?), where we were having sorta similar arguments and running the same risks.
The first phones
My first phone was an Ericsson G-something, and I only remember it because it was the first hand-me-down I got as a broke kid, like many of my ilk, growing up in 90s post-liberalization India. It was a small monochrome candybar, GSM, no color screen, no camera, just calls and texts. It’s crazy that I can still remember that monotone ringtone in my head.
To me, having that device felt like owning a small portal that I could smash open to help me get to a future. Between that, a beat-up motorcycle, a lot of bruises and some limited courage, I was set to face the world.
A lot of us came up that way those days, since you didn’t buy the device, you inherited it, and you pulled it apart because there was no replacing it if you broke it.
After that I moved through the usual feature phones: a Motorola Razr, which still felt futuristic to me as a Star Trek fan (original generation, of course), then a Sony Ericsson K750i with a real camera. None of them ran Android because Android did not exist yet for consumers, but each one made the phone feel more futuristic.
Android Arrival
By the late 2000s I was in tech professionally and dabbling with a Nokia running Maemo. It was not quite Android and not quite mainstream, but it showed me that a phone could be a pocket computer if the software let you in. That idea stuck even as Nokia was going down in flames like a beautiful ship in a sea of colorful Windows Mobile phones, and I held on to that phone as long as I could.
By 2009 the early Android handsets were coming thick and fast, in both senses. The i7500 ran Android 1.5 Cupcake, had a 3.2-inch AMOLED screen, and most importantly it could run CyanogenMod. I flashed it, broke it, reflashed it, and learned more about how a phone worked than any spec sheet could teach. That was way more interesting than my day job debugging large enterprise Java codebases written by hundreds of people before me.
If you used CyanogenMod back then, you know exactly what I mean and we share a kinship.
Later I moved to the Galaxy S, and the i9000 had a 4-inch Super AMOLED screen that looked impossibly bright at the time, a 1 GHz Hummingbird processor, Android 2.1 Eclair, and a 5 MP camera. Android was not just a side project any more, and I remember the version names the way I remember the Pink Floyd catalog: Cupcake, Donut, Eclair, Froyo, Gingerbread and the rest of the desserts.
Vibe flashing
CyanogenMod kept me hooked as a hobbyist hacker through the early 2010s. It gave me CPU governors, quick-settings toggles, and a level of control I could not get from the stock build.
Flashing a nightly build was a small act of James Dean-esque rebelliousness. You downloaded a zip, booted into recovery, wiped what you needed to wipe, and prayed nothing broke. Some mornings the phone came up faster and smoother than it had the night before. Some mornings it boot-looped on that cute Android logo and you spent an hour reading logs and rolling back. The rush came from knowing that if it failed, you could try to fix it yourself, like a pretend phone engineer. if you had buddies with the same obsession, you would show off what you hot-rodded into your custom build.
A lot of folks never understood what was in those builds, and understanding them was never the thing that kept you safe anyway. The recovery partition did that job, because you took a nandroid backup before you flashed and kept a known-good zip on the SD card, which meant that fifteen minutes after a bad build you were back on a working phone. The people who actually lost phones had flashed with nowhere to go back to, or skimmed the instructions and paid for it.
This is why the whole “vibe coding” conversation sounds familiar. You point the agent at a repo, accept a diff you do not fully understand, and find out on the next run whether you still have a working thing. Most mornings the build passes and the demo looks great, depending on what it was for. Other nights, you are tracing a hallucinated import through logs at 1 AM, rolling back to the last known good state.
The argument right now is almost entirely about comprehension. Did you read the diff, do you understand what the model wrote, are you a real engineer if you shipped something you cannot explain line by line? Are you the script-kiddie who grew up into a vibe coder?
The comprehension argument is not wrong on the facts – a recent benchmark called SusVibes found that “the best-performing combination (SWE-Agent + Claude 4 Sonnet) achieves 57% functionality but leaves nearly 80% of working code insecure”, and a broader literature review of 40+ sources found strong evidence for vibe-coding speed but limited evidence that the output holds up over time. Andrej Karpathy has also coined “agentic engineering” to draw the distinction. Simply put, vibe coding is for prototypes and personal tools; agentic engineering is what you do when other people depend on the software.
The part that rhymes with 2010 is that none of that stopped anybody then and none of it will stop people now. Most of the people vibe-coding today do not have the background to parse every diff, and telling them to stop is like telling a broke kid with a hand-me-down phone not to flash the ROM because they might brick it. They are going to do it anyway, because it is the first thing that made the future feel reachable. The work is to build guardrails that support their creativity and let them survive any unwanted behavior.
That is why the rest of this is about restore paths and cheap ways to be wrong. I feel what decides how your evening goes is whether you can restore the steps, and git checkout . is a nandroid backup by another name. When I let an agent run loose on a throwaway script but keep a tight hand on anything that writes to disk or the network, that has nothing to do with understanding one better than the other. It is just that I can undo one of them in three seconds and move on.
Boot-loop or radio
A boot-loop cost you an evening, while a botched radio (firmware that controls cellular communication) or bootloader flash cost you the damn phone and no amount of reading logs brought it back, so everyone who flashed regularly knew which partitions were recoverable and treated them completely differently from the ones that weren’t.
Editing a file today is almost like a boot-loop. Terminal actions like writing to a production database, sending the email, or hitting the payment endpoint are the radio partition, and the steps you take to set either one running remind me of the same.
Most boot-loops had nothing to do with the build, since you had dirty-flashed over the last ROM without wiping cache and dalvik, so you spent the next hour debugging leftover state while blaming the zip. I still lose time to this sort of thing with agents now, except now when the run goes strange, I start reading logs, and 10 minutes later the actual problem turns out to be a stale context window or a half-applied edit from the attempt before or just something that the agent hallucinated.
Building Android from source was the same thing on a longer timescale and you could run experiments with those concepts. You synced AOSP, picked a build target with lunch, ran make, and then waited for stuff to blow up: device trees, vendor blobs, kernel mismatches etc. Every build failed for a different reason and debugging one variable at a time was the only way through with a lot of print statements.
The forum was the eval
You also never flashed a nightly build cold, because there were forty posts under it in the forums from people who had already flashed it that morning on your exact device, saying the camera was broken and bluetooth dropped on reconnect and it was not called an ‘eval harness’. Right now a lot of folks are testing agent workflows sometimes alone and in private, rediscovering the same failures in parallel, or asking the agent to file the issue and flooding the issue log with things nobody reads or just annoys those who do.
These days
These days whats real is that the old discipline came with a guarantee and the new one does not. A nandroid backup always worked, and the zip on the SD card was still the zip I could go back to so fifteen minutes got me my phone restored back every single time. That insurance was the only reason any of us pretenders were brave enough to flash anything in the first place.
A lot of what an agent touches now cannot be restored that way. Version control covers the damage that lives inside the repo and Snapshots and sandboxes cover the machine. We now have microVM platforms that branch and restore a whole filesystem in a quarter of a second, and databases you can fork like a git branch. Beyond that it stops being restoration and starts being cleanup, where a database write gets a hand-written compensating action that reverses the business meaning without putting the old state back. Then there is the last tier and the most embarrassing one, the sent email and the captured payment and the webhook somebody’s server already accepted, wno respite is coming because the state no longer exists and you can’t nuke the context to restart.
All this rambling is not an argument for shipping things you cannot explain into production. It is an argument for experiments under guardrails, keep running the thing and breaking stuff where restore paths exist. Know that for the parts that leave the machine and impact users, the tooling does not save you, and the guardrails are on you. I did exactly that for years, on a phone I could not have afforded to replace, and it taught me more than any amount of careful reading would have. The arguments saying you are not a real engineer unless you can explain every line are making the same argument that got made in 2010, when the objection was that we had no idea what was in those ROMs. It has become a Voigt-Kampff test, and in the book that test was never as reliable as the people administering it believed. They were right about that and it did not matter then. Half the people I know from those forums build software for a living now, and they got there by breaking things on purpose and putting them back.
Six things to consider
- I keep the agent in a sandbox or a worktree for anything exploratory, so the worst case is deleting a directory.
- I give it credentials that cannot reach production, amputating the key is faster than reviewing the diff and it works while I am not around.
- Anything that sends, charges, posts or deletes goes behind a confirmation, and this extra step is very well worth the pain.
- Before a long run I think about how I would rollback, which takes about thirty seconds and occasionally may make me abandon as well if the risk outweighs the goals. Or create a detailed list of steps that have been performed with a checklist that will help me rollback.
- Also usually have a rollback md file or even a one-sentence undo plan in the prompt. Before the agent starts: “If this fails, we revert by X using file.”, this forces the restore path before anything runs for your own peace of mind.
- Time-box unsupervised runs when needed as long agent loops with no manual checks may accumulate stale context and half-baked or partial edits. Always good to inspect and then continue if all looks well.
The goal is to make being wrong cheap enough that I keep trying the next thing without regrets.
Subscribe to posts
New posts on data, AI, Audio and other oddities - straight to your inbox.
Subscribe


