The Gyan-Giver's Confession: How Ops Leaders Take Strategic Tech Debt
- Samrat Biswas
- Feb 16
- 7 min read
Updated: 5 minutes ago
Or: How I Spent a Decade Teaching 200 Engineers to Never Do What I Did on My Birthday

There is a particular species of hypocrisy that only operations leaders can achieve. It requires years of training. You must first spend a decade reviewing other people's code, shaking your head slowly at pull requests, and delivering sermons on modularity, security, and “doing it right the first time.” You must build a reputation. Your team of 200 must associate your teams handle with phrases like “where’s the auth check?” and “this won’t scale past one instance” and “who committed the .env file without .gitignore - no, seriously, who.”
Only then are you qualified to sit down at 12 AM on your birthday and violate every single one of your own commandments in six hours flat.
The Sermon on the Mount(ed Volume)
Let me paint the picture. Monday morning, any given week. I’m standing, metaphorically, it’s a teams call with engineers, tech analysts. I am dispensing gyan. The gyan is flowing. The gyan is torrential.
“Why is this a 1,700-line component? This is not a component. This is a novel. Tolstoy wrote shorter things.”
“Authorization on the download route is not authorization. It’s a lock on the bathroom window while the front door is wide open.”
“You’re installing dependencies at runtime? In production? What’s next, compiling the kernel on every API call?”
“CORS is not a suggestion. ‘Allow everything from everywhere’ is not a security policy. It’s a philosophy of radical vulnerability.”
The team nods. The team takes notes. The team goes forth and does better. This is the natural order.
The Birthday Disruption
Now cut to February 12th, 11 PM. The apartment is quiet. I’ve been pacing since dinner, opening the fridge, staring into it like it contains architectural diagrams, closing it, and going back to my desk. Something has gotten its hooks into me, the realization that the decomposition methodology I’ve been running in my head for a decade might actually be encodable. That the judgment calls I make reviewing epic mappings, the ones my team thinks are some kind of dark art: are actually patterns. And patterns can be software.
I open a terminal. I spin up an AWS instance. Most importantly I select the right playlist. And the clock starts.
What I Built (in one breath)
A tool that takes any requirement spec spreadsheet (that make general sense), forces confidence tiers instead of fuzzy “medium,” detects decomposition gaps and scope signals, and outputs a cleaner, more truthful plan, plus the risk notes your future delivery team will thank you for.
Here is the thing about building at the speed of decision: you become the person you’ve been lecturing about. But faster. With more conviction. And with a growing awareness, somewhere in the back of your skull, that Monday Morning SamB is going to have words with Birthday Night SamB.
Birthday Night SamB does not care. Birthday Night SamB has instant noodles, a FIFA break budget of exactly one match, and an AI coding partner that can generate Express middleware at the speed of thought. Birthday Night SamB is dangerous.
If you want the full build log + the story: what-i-built-on-my-birthday-instead
The Specific Crimes
Let’s inventory the wreckage, because I believe in transparency, especially when the transparency is funny.
Crime #1: The Mega-File. server/index.js - 1,240 lines. App.jsx - 1,700 lines. claudeClient.js - 800 lines. Three files. 3,740 lines.
I have literally made engineers rewrite PRs for committing 600-line files. “Where’s the separation of concerns?” I’d ask, with the quiet disappointment of a father watching his child eat cereal for dinner. Meanwhile, Birthday SamB is writing an entire auth system, streaming pipeline, rate limiter, and admin panel into a single file like he’s trying to win a compression contest.The defense: when you’re building alone at 2 AM and the idea is moving faster than your fingers, extracting to separate modules feels like stopping to fold laundry during a house fire. You know you should. You know the fire marshal will have opinions. But the house is on fire and you’re also building a new room.
Crime #2: Authorization? On Some Endpoints. The download routes check ownership. The review routes, the reformat routes, the enrich routes, the iterate routes - these check that you have a valid token, but not that the token owns the job. This is what’s formally known as an IDOR vulnerability and informally known as “someone could poke around in your spreadsheet data if they guess a job ID.”Monday SamB has given this exact talk. It has a slide. The slide says AUTHENTICATION ≠ AUTHORIZATION in red bold letters. Birthday SamB saw the slide in his mind’s eye at approximately 3:15 AM and whispered, “yeah but it works for now,” then went back to building streaming SSE progress bars.
Crime #3: CORS Wide Open. cors() with default settings. I once described permissive CORS in a team meeting as “leaving your car running with the doors open in a parking lot and being surprised when someone drives away in it.” At 1:30 AM, I typed app.use(cors()) and didn’t even pause. My hands just did it. Muscle memory of sin.Crime #4: The .env File. It was in the uploaded zip. It was right there. Me, the person who has made “never commit secrets” a literal onboarding checklist item shipped a zip file with the .env in it. The only reason this isn’t a catastrophe is that I caught it before GitHub did and I was not actually opening it to the world. But the irony is a load-bearing structural element of my entire professional identity.Crime #5: Runtime pip install. The Python analyzer installs openpyxl on the fly with --break-system-packages. I have used the phrase “dependencies should be declared and installed at build time” so many times it’s practically my LinkedIn bio. Birthday SamB looked at the Dockerfile, looked at the clock, and chose violence.Crime #6: SQLite via sql.js on a Timer. The database writes to disk every five seconds. If the process crashes between writes, data evaporates. I know this. I’ve diagnosed this exact failure mode in production systems. I chose it anyway because at 4 AM, “fragile but fast” beats “robust but it’s almost sunrise and I haven’t started the frontend.”And a lot more...


The Comedian’s Defense
Here is where I’m supposed to be embarrassed. I’m not.
Because “do it right” is sometimes the enemy of “do it at all.”
The constraints of that night were real: six hours, one person, a methodology living in one head, and an AI partner that could write code at machine speed but couldn’t make a single sound architectural decision. Also: a narrow window of momentum that opens without warning and closes without permission.
So the choice was never between clean code and messy code. It was between a working product that encodes a decade of operational judgment and a beautifully architected empty folder.
I chose the product. I’d choose it again.
My team learns that “medium confidence” isn’t an estimate. I learned that “clean” isn’t a product.
The Part Where I’m Not Actually a Hypocrite
But here’s the gyan within the gyan ~ the meta-gyan, if you will:
I know exactly what’s wrong. Item by item. With priority tiers.
The IDOR gaps are P0. They get fixed before any real traffic touches this thing. Token-in-query-string gets replaced with header-based auth. CORS gets locked to specific domains. The .env gets nuked from any public-facing artifact.
The mega-files are P2. They’ll get extracted into modules: routes, middleware, services, prompts. Not because the code doesn’t work, but because the next feature I add will take three times longer if I’m navigating a 1,700-line JSX file with Ctrl+F and prayer.
The SQLite persistence, the memory-only rate limiter, the runtime pip install: these are fine for an MVP serving a handful of users and will melt the moment real concurrency arrives. They’re noted. They’re queued. They’ll get replaced when they need to, and not a moment before.
This is the real point and it’s the one I try to teach underneath all the gyan:
The skill isn’t avoiding tech debt. The skill is knowing exactly what debt you’re taking on, why you’re taking it on, and what the repayment schedule looks like.
Reckless debt is when you commit the .env and don’t notice. Strategic debt is when you write a 1,240-line server file at 3 AM because the alternative was not having a server at all and you already have a mental P2 ticket to decompose it.
Cut corners, sure. But cut the right corners, at the right time, for the right reasons and write down (on flip flops or neurons) which corners you cut so Future You doesn’t spend three days debugging something Present You could’ve documented in a comment.
The Repayment Plan
So here it is. The gyan-giver’s ledger. What was borrowed, what’s owed, and the order it gets paid back:
First: Locks on the doors. Authorization on every job-specific route. Token out of query strings. CORS locked to actual domains. Secrets purged from every distributable artifact.
Next: Structural cleanup. Extract routes and middleware out of the monoliths. Separate prompt templates into versioned files (the “constitution versioning” instinct was right; the execution was deferred). Move runtime dependency installs into the build step where they belong.
Before scale demands it: Replace the parts that work at low traffic and melt under concurrency: persistence model, rate limiter, and integration tests against real spreadsheets. The ugly ones. The merged-cell ones. The ones produced by actual humans in actual enterprises.
Always: Surface more of the analysis intelligence in the UI instead of hiding it in downloaded files. The engine is doing sophisticated work: decomposition gap detection, confidence tier forcing, scope signal analysis. Right now, the user has to download an Excel file to see most of it. That’s like building a Michelin-star kitchen and serving food through a slot in the wall.
Some of this is already done (an update from the Monday early morning). The redemption arc, it turns out, moves faster than the sin arc. Fewer extra snacks required.

The Punchline
I’ll be back in front of 200+ engineers on Monday. Someone will push a PR with a 600-line component. I will look at it. I will take a breath. And I will give gyan.
But this time, I’ll add something I didn’t used to say:
“This is too big to review as-is. Break it up. But also, tell me why it’s this big. If you were moving fast because the idea was moving fast, and you know exactly where the seams are, and you’ve already thought about where to split it, then we’re not having a code quality conversation. We’re having a scheduling conversation.”
Because the best engineers aren’t the ones who never take on debt. They’re the ones who can name the debt, explain the trade, and plan the payoff.
I’ve got mine tracked. The list is generous. And I’m good for it.
If this essay hit a nerve, here’s the next step: I can help you learn the patterns, walk the process, and fly into repeatable delivery without the midnight heroics. You may reach out to me at linkedin, substack or samratbiswas.com.
And if you want anything production-grade, secure, fast and scalable, I do not do that alone. My team at Unified Infotech build software that the Monday version of me can sign off on.
Code/Repo (MVP, documented debt included): atomikd-requirement_analyzer
p.s. This was never exposed to the public internet and will be patched before any real users find it.


Comments