Code Is a Liability, Not a Feature

Who has reviewed MULTIPLE 2000+ lines PRs in the last 24 hours ? It’s not a unusual to many software engineers today. In the past, I would have blocked it. But if I block it now, I’m not “embracing AI.” Maybe I’m NOT “embracing AI”. That’s a bold statement for engineers who want to keep their job. Well. Not in the way how quickly AI is able to puke code today.

To counter that, the AUTOMATED PR BOT then generates 1000+ lines markdown to explain the PR. Along with the 20 autogenerated PR review comments.

Ngl. I hate my job everyday. I’m also so excited. Because this industry has a HUGE problem. You know what engineers love the most? Problems. We sometimes even invent them — just to keep our jobs solving problems. What an exciting time to be an engineer. We have yet invented another problem with yet another solution.

Code Is A Liability, Not A Feature

Code is artifacts produced based on the assumptions of features and functionalities derived from the core idea. A friend once asked me, isn’t Reddit (sorry, self-plug, I work for Reddit now) just a website where people can post, why do we need so many people?

Idea                    ← what the person thinks it is
 └── Feature            ← what the engineer thinks it is
      └── Functionality ← what the engineer decided without asking
           └── Code     ← what the engineer (turned llm) writes

In a way, they’re not wrong. People come to post and comment. Simple.

But as an engineer I immediately start decomposing: people need accounts, create posts, comment, upload images and videos, vote, get recommendations, search. Wait — searching text is different from searching images and videos. Do we need to transcribe media into text? The list goes on.

When the assumptions are right, code is an asset.
When those assumptions are wrong, code is a liability.

To give it an example. How many of my fellow platform engineers have migrated from data center → single cloud → hybrid cloud → back to data center + cloud(s)? I call this the biggest modern day platform engineering Ponzi scheme. They all work. Every new CTO wants to make a change to show they made a change. (See, we do invent problem if you don’t have one.)

As business objectives shift, engineers need to evolve the existing codebase to support a new set of features. Except usually we frame it as migration (to the future) to get support from the business. As an engineer, I call it paying off tech debt.

The Pipeline Is Not So DRY Anymore

DRY (Don’t Repeat Yourself) is a term software engineers use to express a piece of logic in the most concise way possible.

Say every Tuesday and Thursday you play tennis. But if you’re too tired, you skip it — and when you skip, you need to find someone to play for you and let your friends know.

Simple enough. But then you add more rules: Tuesday, X is usually available. Thursday, Y is usually available. So one Thursday you call Y — not available, so you call Z instead. Next Thursday you forget you usually call Y and go straight to Z. Now Z isn’t available either. And you’re in panic mode. Alternatively, because Y is usually more available, you establish an order to always ask Y first then Z on Thursday. This way you maximize your chance of finding another person to play for you while minimizing the work. This is an IRL version of DRY in simple terms.

Why is this important? Because code is trying to automate manual tasks — and our manual tasks, as you can see, can be quite complicated. If you express your task in a complicated way, the code becomes complicated too. That’s why engineers come in and try to simplify the implementation. They’re trying to find patterns in the task and express it in a more concise way. I’m sure you’ve heard of spaghetti code. When you express your logic in a spaghetti way, things do break more often because no one understands what it does.

Disclaimer: I’m not saying DRY is the bible of software engineering. It’s just a principle that LLMs absolutely don’t optimize for. I don’t blame these LLM companies. The more tokens you use, the more they charge you. Why would they charge you less when they can charge you more? Remember, engineers love to invent problems.

Now, this diagram exaggerates more on the code-gen part. I’m sure PMs have their daily chat with AI too to figure out what 10 new feature ideas they can suggest. No offense to PMs — your usage of LLM is miniscule compared to the code engineers generate. Engineers can in fact easily 100x themselves thanks to AI.

What I want to show is: code is an artifact of the features we want to implement. Remember? Anything that doesn’t adhere to the intent is DEBT. If we don’t have clarity on the intent, we don’t have clarity on the implementation. At the scale we’re generating code today, dead code is not a common metric to collect — but if you measured it, I’m fairly sure the Post-AI number would be through the roof.

From Whiteboard to Production

You’ve probably seen this in many system design interview. Can you build a tennis booking app? The engineer in the interview will start by listing out requirements like:

  1. Player needs to be able to search for available courts
  2. Player needs to be able to book available courts
  3. Player needs to be able to cancel existing booking
  4. Player needs to be able to pay for the court
  5. A club manager needs to be able to add available court times and price
  6. [Optional] A club manager want to see the overall reservations in the club

And then the engineer breaks down the requirements into implementation:

def search_available_courts(start_time, end_time, location) -> []Courts:
    # go to database and find clubs within certain proximity of the location
    # go to database and find courts of those clubs
    # go to database and scale what courts are available within the specified time
    pass

def book_courts(start_time, end_time, court_id) -> Reservation:
    # add a record of the court_id to create a record of reservation using start and end_time
    # if the court is already booked, return unable to book
    pass

def update_existing_reservation(reservation_id) -> Reservation:
    # update a record of the court_id to create a record of reservation
    pass

def pay_for_reservation(reservation_id):
    # call stripe to charge for the specified reservation
    pass

In this very simple example, before the engineer writes a single line of code, they already know what they’re going to build. It’s not so easy for them to implement something widely different from what’s expected — as long as we agree on what we want to build. As the engineer goes ahead and adds external API, database integrations, and business logic, these function definitions eventually become the actual backend of the application.

Similarly, if our human attention can shift from reviewing 2000+ line generated code to decomposing the implementation into well-defined, composable pieces, we can generate much higher quality code, that’s also much easier to test and review.

Contract First Development

Today, design docs are optimized for human understanding. To drive team alignment, gather feedback, get sign-offs. Now that we have this overly productive (and also uncontrollably creative) coding agent to help on the implementation side. How to make sure the implementation adheres to the design? As a senior engineer, what will you do? You’d write the implementation spec so clearly so there’s no room for interpretation and much easier to verify.

This is what I call Contract First Development. This is not an industry term. It’s just a framework I’ve been toying with in my free time. Has nothing to do with my job.

I believe the future of software development is not MORE code but to find the right level of natural language abstraction that’s both easily understood by humans and executable by AI.

10caldev / demo
1 / 5
Step 1 — User Input
Describe Your Business
No wireframes. No spec doc. Just a description of the business.
User prompt

A marketplace connecting tennis, pickleball, and padel club owners with players looking for discounted court time. Club owners list slots with dynamic pricing — discount tiers that grow as the booking window shrinks (10% off 48h before, 30% off 24h, 50% same-day). Players set price and notification preferences. Payment is immediate on booking; no cancellations within 24h. Platform takes 5%. MVP: one market, web only.

Step 2 — Product Agent
Problem Statement
Features and personas are generated automatically.
Core Problem

Clubs have unsold court slots — pure revenue loss. Players want affordable access but can't find discounted availability. No marketplace connects them with automatic time-decay pricing.

Personas
Club Owner Player Platform Manager
Success Criteria
Club live <10 min Book in <3 taps Zero overbooking Discount tiers auto-apply
Step 3 — Engineering Agent
Contract First Development
Backend interface derived from features and personas.
Court Booking
Player discovers a discounted slot, pays immediately, and gets a confirmed booking — no overbooking possible.
Must Have
3 API Endpoints
GET
/api/v1/public/slots Browse available slots with live discount prices
?sport &date &max_price
POST
/api/v1/player/bookings Confirm booking and charge card immediately
Auth SELECT FOR UPDATE Stripe
PATCH
/api/v1/player/bookings/{id} Cancel — enforces 24h window platform-side
Auth 403 if not owner
18 endpoints total 6 DB tables locked before build
Step 4 — Builder Agent
Backend generated, tested, and running.
Fully automated. Agent automatically discover and fix build issues.
Phase 1 — Code Generation automated
1
Define the file interface
Agent maps every file: path, exports, signatures. All code generated afterward is validated against this.
2
Generate backend code
Agent writes every file and automatically validates it against the interface. FastAPI routes, SQLAlchemy models, Stripe integration.
Phase 2 — Automated Testing automated
3
Lint & fix
ruff + isort run automatically. If errors remain, an LLM agent patches the files and retries — up to 2 rounds.
4
Build container & health check
Docker image built, container started, GET / probed. Pass → done. Fail → LLM reads the error and patches.
Running · localhost:8080
Health check passed · Stripe mock · SQLite in-memory
Step 5 — Frontend Agent
Frontend generated from the same contract.
Role-scoped pages, hooks, and API clients — all derived automatically.
localhost:3000/search
Find a court
Ace Racket Club Tennis
Today · 9:00 – 10:00 AM
$40
$20
50% off
Padel House Padel
Today · 6:00 – 7:30 PM
$60
$42
30% off

The demo above is extracted from a real generated example — a simple business idea, end to end. From ideation to implementation, each step is derived in natural language, editable by humans, and executable by AI.

10caldev Beta

If you’re curious about how this works in real application, I’m working on the 10caldev beta. The dream I’ve always had that everyone can build their own software — might actually be within reach now. Stay tuned.

comments powered by Disqus