A teammate’s design feedback on the V3 pricing page landed mid-morning on April 13. The card structure was too dense, checkmarks were missing, the typography did not match the rest of the product, and checkout-bar behavior on mobile was undefined. The list was longer than a cosmetic pass could fix.

I had a choice. Keep iterating on the existing V3 branch, which already had a week of work in it, or look at what that branch was actually doing to the codebase.

So before touching anything else, I read through the branch.

the prototype had been building up debt

The pricing prototype had grown inside shared code paths. Account-specific presentation behavior was accumulating inside conditionals that also handled an existing purchase flow. It was not an intentional architecture decision; it was the cumulative result of small iterations without a clear boundary or dependency map.

The shared purchase path was live and consequential. A presentation change could have effects beyond layout if it altered shared state, totals, eligibility, or navigation. The prototype was not automatically unsafe, but each additional iteration increased the need to understand the entangled callers and contracts.

I saved the branch. Then I closed it and started over.

one boundary stopped the leakage

The restart began by separating the prototype presentation methods from the existing path and documenting how eligibility, authorization, and shared data would be handled. An account-type signal could choose a presentation route, but it was not treated as authorization by itself; protected actions still required their own server-side checks.

That boundary made later UI iterations easier to review: card padding, checkmark rendering, typography alignment, mobile overflow, checkout-bar structure, and CTA states could be assessed against a smaller, documented surface. It reduced the chance of incidental legacy-path changes; it did not eliminate the need for tests, authorization review, and release verification.

what the release actually required

The release work showed why the phrase “UI iteration” can hide real dependencies: asset compilation, legacy headings, navigation behavior, and responsive layout all needed their own checks. Some of those tasks reflected how long the prototype had sat near shared paths; others were normal release work revealed by a more complete review.

AI assistance accelerated the iteration, but it did not know which legacy state was load-bearing unless that context and the relevant checks were included in the task. Identifying those limits remained part of engineering review.

the sequence worth stealing

I have done a version of this more than once. A prototype accumulates. It starts to feel expensive to redo. Outside feedback, a code review, a failed test, a list from a designer, makes the scoping problem visible for the first time. The temptation is to patch around it.

Sometimes the right move is to preserve the branch as a reference, restart from a known-good point, and define the scope before adding more UI work. That choice should follow a comparison of migration cost, shared dependencies, and rollback options rather than a reflex to restart.

AI makes UI deltas inexpensive to generate. It does not make mixed-scope code safer. The team still needs to decide where the experiment may live, what it may touch, how it is authorized, and how it will be verified or removed.