Generation speed hides unfinished work. A vibe-coded web app can look complete while its form drops leads, its error route returns 200, or its production build depends on an environment variable that exists only on one laptop.
Use this guide after the feature works locally and before you call it shipped. It extends the Five-Gate Verify Loop from one coding session to the whole application.
Kill the default approach: screenshot-based launch
The common launch test is a visual pass: open the homepage, click around, deploy. That proves the happy path rendered once. It does not prove the build is repeatable, data survives bad input, contact delivery works, or the application can recover from a failed dependency.
Replace the screenshot with a receipt. Every important behavior needs a command, an observed production result, or an explicit owner.
By the end you will have
- A release sequence for code, data, security, UX, and operations
- A paste-ready Vibe App Production Receipt
- A failure-injection pass for paths agents often skip
- A rollback decision made before deployment
- A short post-launch watch window with named signals
Freeze the promise before testing
Write the release promise in one sentence:
A visitor can submit a qualified enquiry, receive a clear confirmation, and the team receives one replyable email.
That sentence identifies the path that must survive. A dashboard release might name authentication, one data mutation, and an export. A checkout release might name price, payment confirmation, and fulfilment.
Now list what is outside the release. Agents tend to repair nearby code while verifying. A written exclusion keeps the diff from growing after product behavior is already at risk.
Prove a clean build
Run the same commands CI or the hosting platform will run. Do it from a clean dependency state when the change touches package resolution.
pnpm install --frozen-lockfile
pnpm typecheck
pnpm lint
pnpm test
pnpm buildUse the commands the repository owns. Do not paste this block blindly into a project that uses npm, Bun, or a different test runner.
Review build output for warnings, unexpected dynamic routes, oversized assets, and pages that changed rendering mode. A green exit code can coexist with a costly architectural change.
You should see: one reproducible command chain and no undocumented step performed by hand.
Test boundaries, not only examples
Agent-generated code often handles the sample value from the prompt. Production sends empty strings, repeated clicks, expired sessions, slow networks, and unexpected response bodies.
For each mutation, test:
- Missing and malformed required fields
- Values at the minimum and maximum accepted length
- A duplicate submission
- An unauthenticated or expired session
- A dependency timeout or non-JSON response
- A retry after an ambiguous failure
The server must validate again even when the form validates in the browser. Client checks improve feedback; they do not establish trust.
For money, account, deletion, or external-message actions, add an idempotency rule. A retry should not charge twice, create two records, or send the same email twice.
Walk the production path
Local success does not verify environment variables, production domains, mail reputation, OAuth callbacks, database policy, or analytics.
After deploying a preview or production candidate:
- Open the public URL in a private browser session.
- Complete the primary journey with a fresh test identity.
- Confirm the resulting database row, email, payment, or external action.
- Refresh and repeat the last action to test duplicate handling.
- Open the same path on a phone-sized viewport.
- Confirm the expected analytics event fires once.
Keep test data obvious and remove it through the normal product path when possible. Direct database cleanup can hide a broken delete or retention flow.
Inspect the security boundary
Search for secrets before shipping:
git diff --cached
rg -n "(API_KEY|SECRET|TOKEN|PRIVATE_KEY)" . \
-g '!node_modules' -g '!.next'Then inspect each server mutation:
- Is identity derived on the server?
- Is input parsed against a bounded schema?
- Can one tenant read or change another tenant's data?
- Does the response expose stack traces or provider bodies?
- Are rate limits or abuse controls appropriate for the cost?
- Are logs free of credentials and sensitive message content?
Do not ask an agent to prove authorization by reading the UI. Authorization lives at the data or server boundary.
Check mobile, keyboard, and failure UI
Run the primary path at 320, 375, 768, and a desktop width. Check document width against viewport width so clipped overflow cannot hide off-screen.
Use only the keyboard for navigation, dialogs, and forms. Zoom to 200%. Trigger loading, empty, error, and success states. A button that works only with a mouse or a validation message that cannot receive focus is unfinished product behavior.
Test a missing route and a server failure. The missing route should return a meaningful 404, not a styled page with a successful status. Errors should help the user recover without exposing internal details.
Decide rollback before deploy
Record three items:
- Last known-good deployment or commit
- Data compatibility of the rollback
- The signal that triggers rollback instead of another patch
A code rollback cannot safely reverse a destructive data migration. For schema work, use an expand-and-contract sequence: add compatible fields, deploy readers and writers, migrate data, then remove the old path in a later release.
Magnet: Vibe App Production Receipt
Copy this into the pull request or release issue:
# Vibe App Production Receipt
PROMISE
[ ] One-sentence user outcome:
[ ] Explicitly out of scope:
BUILD
[ ] Frozen install succeeds
[ ] Typecheck, lint, tests, and production build pass
[ ] Build warnings reviewed
BOUNDARIES
[ ] Bad, empty, duplicate, expired, and timeout cases tested
[ ] Server validation and authorization verified
[ ] Retry behavior is safe
PRODUCTION
[ ] Primary journey completed on the deployed URL
[ ] External result confirmed: email, row, payment, or job
[ ] Mobile, keyboard, zoom, loading, empty, error, and 404 pass
[ ] Analytics event observed once
OPERATIONS
[ ] Logs exclude secrets and sensitive payloads
[ ] Rollback target and trigger recorded
[ ] Owner watches errors and conversion after launchYou should see: evidence beside every checked line. An unchecked line either blocks launch or carries a named owner and accepted risk.
Failure modes
| Symptom | Missing proof | Fix |
|---|---|---|
| Preview works, production fails | Environment parity | Exercise the deployed URL with production integrations |
| Users create duplicate records | Retry and idempotency | Bind requests to a stable operation key |
| Green build, broken form delivery | External result verification | Confirm inbox or provider receipt, not only HTTP success |
| Mobile page clips horizontally | Viewport matrix | Measure document width at the smallest supported size |
| Rollback makes data unreadable | Migration compatibility | Use expand-and-contract releases |
When not to run the full checklist
- A throwaway prototype will be deleted and has no real users or credentials
- A documentation-only edit changes no executable behavior
- An emergency rollback returns to a known-good release; run the affected-path smoke test first
Any change involving money, authentication, deletion, secrets, customer messages, or production data keeps the full boundary and rollback sections.
Watch the release after it lands
For the first watch window, choose the few signals attached to the release promise: error rate, successful completions, latency, delivery failures, and support reports. Compare against the previous deployment when traffic is sufficient.
Do not call the release healthy because the deployment platform says Ready. Ready means the artifact started. The production receipt proves the user journey.
path
Install a repeatable shipping system
Agent OS Setup turns scope, repository rules, verification commands, approvals, and receipts into a working operating system for your team.
Your next action: copy the Vibe App Production Receipt into the next release and leave each box open until evidence exists.