
Vibe coding means asking an AI to build or change software through ordinary-language instructions. What if, after you add a new feature, changing a filter makes the totals wrong, or saved data disappears after a refresh? Developers call that a regression. In everyday terms, it means a change in one place broke something else that used to work.
I added priority, due dates, and inline title editing to one local task app, one feature at a time. Within the automated and interface checks I actually performed, I found no new-feature defect or regression, and I sent no correction prompt to the AI. This result came with important conditions: the baseline request already included tests and storage-error handling, and every later stage began from a version whose executed checks had passed. I also could not execute every planned browser check, so all four stages remained “partially verified.”
In this article
The short answer, before the details
- In this one case, every executed check still passed after three feature additions.
- “Zero defects” means none were found by those checks, not that the app was proven bug-free.
- Here, the code, tests, and list of behaviors to recheck grew along with the features. The result supports the habit of checking old behavior and saved data after handing the AI another feature.
The practical question from this case is not only whether the AI produced the first version. It is also whether you can repeat the same verification routine every time you add a feature.
Five things to recheck when you add a feature
- Retry the old buttons in the same order before focusing on the new feature.
- Change filters and check that the visible list and global totals do not contradict each other.
- Refresh or reopen the app and confirm that entered data remains.
- Check that the new feature did not silently alter unrelated fields such as completion or due date.
- If you find a problem, describe the correction specifically to the AI, then rerun the entire routine after the fix.
I did not need the fifth step in this run, but it was a response step defined before the experiment, not a rule added after seeing a favorable result.
I changed one local task app in four stages
I used the AI coding tool Codex to build Pocket Tasks, a local app with no external server or real personal data. The tool's screen did not show the exact model name, so I do not name the model in this article. The baseline request covered adding, completing, and deleting tasks; status filters; summary counts for all, active, and completed tasks; browser storage; unit tests; and storage-error handling.
Each later stage started from the preceding snapshot—the saved copy of the app at that point—whose executed checks had passed:
- S0: baseline app
- S1: priority and a combined status-and-priority filter
- S2: due dates and an overdue filter
- S3: editing a title inside the task list
At every stage, I checked JavaScript syntax. From S1 onward, I reran all earlier automated tests without rewriting them and added tests for the new feature. I then used a browser tool to check adding, completing, filtering, and totals in the interface. On refresh, I checked the title, completion state, priority, and date fields that existed by that stage.
No regression appeared in the checks I ran
| Stage | Feature added | Automated tests | Overall label |
|---|---|---|---|
S0 |
Baseline app |
7/7 passed |
Partially verified |
S1 |
Priority and combined filter |
10/10 passed |
Partially verified |
S2 |
Due dates and overdue filter |
15/15 passed |
Partially verified |
S3 |
Inline title editing |
18/18 passed |
Partially verified |
I counted a product defect as a problem in the new behavior and a regression as an earlier behavior that stopped working. Across the executed checks, the product-defect count was zero. The observed regression count for S1–S3 was also zero. Correction prompts and manual code changes after validation were both zero.
I also split the interface checks by stage. In S1, tasks created before the priority feature existed showed medium priority, as requested. In S2, the status, priority, and due-date filters worked together so that only tasks meeting all selected conditions remained, while the summary counts stayed unchanged when the visible list became smaller. In S3, editing a title preserved completion, priority, and due date, and the saved values remained after a refresh. The test-tool problem that arose during these checks is explained below.
The automated layer used Node.js's built-in test runner, which reports an exception during a test as a failure. The app stored browser data in localStorage, which keeps values for the same site address. Separately from the state and storage logic covered by the automated tests, I also checked in the browser that values remained after a real refresh. (Node.js Test Runner, MDN Web Storage API)
Why every stage remained “partially verified”
The browser tool I used could not change stored values directly, so I could not reproduce in the interface how the app behaves when it meets corrupted saved data. That case was checked only by automated tests. I ran deletion in the S0 interface, but I did not repeat it in later stages because the browser tool required a separate safety confirmation at the moment of the action. The automated test kept from S0 continued to cover it.
During the final refresh check, the browser tool timed out twice while trying to locate a specific on-screen item. I confirmed the saved title and the other fields by reading the whole screen structure and the full item list at once. I did not count this tool problem as an app defect, but I also did not record the narrow lookup as a clean first-attempt success. The stages remained partially verified because the planned malformed-storage browser case was not run and deletion was not repeated in the interface after S0.
The pass counts and zeros therefore describe the behaviors that were checked. They do not guarantee behavior in every user environment, in a different app or prompt, or in maintenance on already broken code.
Reference: code size, complexity, and timing
The application grew from 214 to 361 nonblank lines, while the test code grew from 37 to 123 nonblank lines. Cyclomatic complexity counts how many independent paths branch through source code. Under the same ESLint 9.35.0 classic rule on the same day, the highest per-function value rose from 8 to 10; no function exceeded the predeclared threshold of 10. That ESLint version emitted an end-of-support warning, so I used it only for a fixed same-day comparison. Line count and complexity are supporting signs that there was more to check, not quality scores. The international standard ISO/IEC 25010 likewise treats product quality as a set of characteristics and subcharacteristics rather than a single score. (ESLint complexity, ISO/IEC 25010:2023)
The time from request to first delivery ranged from 52 to 122 seconds per stage, and validation took 72 to 126 seconds. The requirements and number of checks differed by stage, so these timings do not show that the AI improved or deteriorated. The final validation also included time spent distinguishing an app problem from a test-tool lookup problem.
A feature is finished only after the old behavior is retested
In this one app, all three features were added without a correction prompt, and I found no earlier behavior that broke in the checks I ran. But this was a single continuous case in which every stage began from a snapshot whose checks had passed. It did not measure the cost of extending an already broken app.
Maintenance does not end when the AI produces code. A feature is only finished after you have checked that yesterday's behavior still works today.
AI was used to assist with research and drafting. The author independently verified and edited the final article.
댓글 남기기