The short answer
You do not decide rescue versus rebuild in a meeting. You score the repo.
  • Score five lines. Modularity, schema, tests, secrets, and ownership of IP. Three rescue marks means you keep the running product.
  • Rescue the money path first. Keep the URL that already takes Stripe payments and repair the risk around it.
  • Rebuild only against a spec. IndiaNIC writes the spec from the live prototype, then cuts over module by module. A blank rewrite is a second demo.
  • Do not pause sales for aesthetics. Ugly folders are cheaper than a quiet checkout.

I once sat in a Pune conference room while a founder argued for a full rewrite of an AI copilot that was already taking real card payments. The embarrassing part was not the code. The embarrassing part was that we found the payments, the prompts, and the users in one afternoon, and none of those facts had been written into the rewrite brief.

A prototype is not a moral failing. It is a bet that shipped. The question in 2026 is not whether the folder names please a visiting engineer. The question is whether you can put a ceiling on risk without throwing away the only evidence you have that customers care.

Pencil-marked evaluation sheet and mechanical pencil on a wooden desk
Score the repo before you argue about rewrite versus rescue.

The origin of a rewrite that should not have started

The copilot had been generated on a weekend. A Bolt export had become a Next.js app. A freelancer had pasted an OpenAI key into a file named secrets.local.js and later into a client bundle. The database was one Postgres table with a single jsonb column called data. Tests did not exist. Users did.

The founder had been told this could not be production. So he paused outbound sales, hired a second team, and commissioned a clean architecture. Eleven weeks later the clean architecture still had no checkout. The original app still had customers asking why login failed after a password reset.

That is the pattern I keep seeing. The rewrite is sold as courage. It is often avoidance. I do not romanticise vibe-coded apps, and I do not burn a working checkout because the routes live in one file. You score the repo. Then you choose. The unglamorous version of that work lives on the IndiaNIC blog.

When should you rescue an AI prototype instead of rebuilding it?

You should rescue an AI prototype when it already has users, the core flows can be named, and the damage is local. Rescue keeps the running system, freezes behaviour in a spec, and repairs the riskiest layers first. Rebuild is for when nobody can tell the truth about what the code does.

Local damage looks like this. The model key is in the browser. One table holds users and invoices as JSON. There is no test on the pay wall. A contractor still owns the GitHub organisation. Each of those is a repair. None of them, alone, is a reason to throw away the product. Taste is not a score.

The five-line scorecard founders skip

Meetings produce opinions. Scorecards produce decisions. I use five lines: modularity, schema, tests, secrets, and IP. If three or more lines say rebuild, I stop arguing for rescue. If three or more say rescue, I stop the theatre of a greenfield rewrite.

Modularity is whether you can change the chat UI without breaking billing, and whether the model call lives behind a server route. According to the Next.js composition guidance, server code and client code are not the same privilege. A Client Component that calls OpenAI is a secret on the public internet.

Schema is whether PostgreSQL can say what a row is. Data from the PostgreSQL constraints documentation is blunt: a table without keys and checks will not survive a second engineer. Test coverage, for a prototype, means a machine can prove login, pay, and the one AI action that costs money. I would rather have three Playwright journeys than eighty unit tests on a prompt formatter. According to the OWASP Web Security Testing Guide, session handling is testable. If you cannot test it, you do not have it.

CriterionRescue ifRebuild if
Code modularityRoutes, UI, and model calls can be named and moved without a full rewriteOne generated file owns UI, billing, and the model, and nobody can split it
Database schemaTables exist, or JSON can be lifted into users, threads, and payments in a weekThere is no honest identity for a user or a charge, only a blob dump
Test coverageYou can add Playwright around login, pay, and the paid AI actionBehaviour cannot be described well enough to write a failing test
SecretsKeys can be rotated and moved server-side without redesigning the productThe client is the integration layer and every secret has already leaked into git history
Ownership of IPThe company controls the repo, the accounts, and the vendor contractsA freelancer, a tool account, or a silent co-founder still owns the source of truth
Score in writing, in one sitting. Open the repo, the database, the cloud accounts, and the legal folder. Mark each line rescue or rebuild. Do not debate a line that you have not opened. The scorecard is a record of what you saw, not a mood.

How IndiaNIC runs a spec-driven rebuild

When the scorecard says rebuild, we still do not start from a blank Figma file. IndiaNIC’s spec-driven rebuild starts from the running prototype. We click through the live product and write down the click path, the data written, and the error the user already lives with. That record becomes acceptance tests before anyone opens a new app router.

The rebuild then happens in bounded modules: identity, billing, the model boundary, then the screens. We dual-write. Old rows keep working. New tables gain constraints. When the new path matches the spec, we cut traffic. The old URL can stay.

What does a spec-driven rebuild actually change?

A spec-driven rebuild starts from the running prototype, not from a blank design file. We record what the product does today, turn that recording into acceptance tests, then rebuild one bounded module at a time against those tests. Data moves with dual writes. Cutover happens when the new path matches the spec, not when someone feels proud.

The change is that the team stops arguing about frameworks and starts arguing about behaviour. “Does the failed payment retry?” is a better fight than “should this be Remix.”

A rewrite without a spec is just a second prototype with a higher burn rate.

A worked example: the Ahmedabad copilot

Here is how the five lines landed after that Pune meeting, once we opened the repo in an Ahmedabad war room the next morning.

Modularity scored rescue. The generated Next.js app was messy, but API routes existed and chat was separate from billing. Schema scored “rebuild the data layer, not the company.” One jsonb table is a smell, not a death certificate. We lifted users, threads, and charges into ordinary tables. The blob told us what customers had actually stored.

Tests scored rescue-with-urgency. There were none, so we wrapped login, the Stripe checkout session, and one paid completion in Playwright the same week. Secrets scored “repair now.” The OpenAI key had been prefixed for the client. We rotated it and moved the call to the server. IP scored rebuild of ownership, not of code. The freelancer still owned the GitHub org and the Stripe account sat on a personal email. We transferred both before we wrote another feature.

Final tally: four rescue, one ownership repair. We stood the rewrite team down. The original URL kept the customers. Two weeks later the keys were rotated, the webhook verified, and the fat table had been split.

What you should do this week

Do not schedule a rewrite workshop. Schedule a scoring morning. This is the order I use.

  1. Open production, not Figma. Write the five money paths on paper: sign up, login, pay, the AI action, refund or cancel.
  2. Clone the repo and mark modularity. Can you name the server file that talks to the model? If the answer is “the page,” that line is in trouble.
  3. Open the database. List tables. If you have one blob, dump ten real rows and name the fields you would promote tomorrow.
  4. Add one Playwright test around checkout, even if it is slow and ugly. A red test is a spec. A slide deck is not.
  5. Rotate every key that ever sat in a NEXT_PUBLIC_ variable. Then search git history. Assume it is public.
  6. Confirm who owns GitHub, Vercel, Stripe, and the OpenAI org. Transfer anything that is still personal.
  7. If three or more lines say rebuild, write the spec from the live product before anyone opens a new repo.

If the scorecard is mixed, rescue the money path and rebuild the unsafe boundary. That is not indecision. That is how grown systems are made. The market does not pay you for a tidy lib folder. It pays you for a product that still works on Monday.

Frequently asked questions

Is a messy generated Next.js app automatically a rebuild?

A messy generated Next.js app is not automatically a rebuild. Generated folders are a style problem until they hide billing, secrets, or identity. If you can isolate the model call and name the payment path, rescue it. Rebuild only when the generated file is the product and cannot be split without inventing behaviour.

How long should a rescue take before I admit I need a rebuild?

A focused rescue should prove itself in two weeks: keys rotated, money path tested, worst table lifted, ownership transferred. If after that you still cannot describe a user or a charge, stop. That is a rebuild. Do not stretch a rescue into a quiet six-month rewrite with no spec.

Do I pause sales while we score or rebuild?

Do not pause sales while you score. Scoring is a morning, not a quarter. If you must rebuild, keep the old URL live and cut over one path at a time. A silent market is a more expensive bug than an ugly repository. Customers can live with a plain UI. They cannot live with a vanished product.