A demo can be convincing and still leave the real release decision unanswered. Before inviting customers into an AI-built app, put one proposed commit and one deployed environment through six checks. For each check, record observed evidence, the person who owns the decision, and whether you will ship, hold, or remove that feature from the first release. This sheet is a coordination tool; it is not a security audit or a claim that every web app needs the same controls.
Fix one release candidate
Write down the repository, branch, PR, latest commit, target environment, and features included. Stop accepting new agent edits while reviewing that candidate; if a commit changes, repeat checks affected by its diff. GitHub can enforce required reviews and status checks on protected branches when configured, but those checks only say what the repository asked them to measure. In Canopy, use the session's checkout and PR context with the running service and Preview where supported. Verify the installed app release before assuming a current-main feature appears in your build. A founder can own product acceptance; a qualified developer or security reviewer should own technical judgments they are asked to approve.
- Link the exact PR and deployment artifact or commit.
- List any planned feature that will stay disabled at launch.
- Name the person who can stop the release if a check fails.
Check the user journey in the running app
Try the core journey as a new account and an existing account. For a paid report app, that could be sign up, create a report, see it after refresh, log out, and encounter a failed request. Record the URL, account role, input, expected result, observed result, and date. Repeat on the actual preview or staging environment as well as locally; a local success does not prove deployment configuration. Inspect browser errors, API responses, and service logs when a path fails. The UI acceptance and debug guides go deeper on visual and network evidence.
| Gate | Minimum evidence | Who decides |
|---|---|---|
| Core journey | Success and failure observed in the target environment | Product owner |
| Data access | Another user or team is denied at the server/data boundary | Technical or security reviewer |
| Persistence | Existing records survive the release change; restore path is known | Database owner |
| Payment, if enabled | Sandbox payment reaches one correct entitlement; failure stays unpaid | Billing and technical owners |
| Release operations | Exact commit, deployment target, logs, rollback contact | Release owner |
Review identity, permissions, and secrets
A working login does not establish that one customer cannot request another customer's object. Have a reviewer state the allowed roles and test a direct cross-user request at the backend or database boundary. OWASP's ASVS provides a broader framework for choosing security verification requirements; this decision sheet covers only a small, product-specific slice. Check that live credentials are absent from the PR, public comments, browser bundle, and copied agent prompts. If a key was exposed, stop the launch path and follow the provider-revocation workflow before debating Git history. The access-control and leaked-key guides contain the detailed evidence and response steps.
- Do not approve a vague claim that RLS or middleware is 'enabled'; inspect the rule for this object and action.
- Test allowed access too, so an always-deny implementation does not masquerade as a working feature.
- Record any security assessment the product actually requires beyond this small checklist.
Know which data survives and how it comes back
If the release changes a database, inspect the migration SQL, target project, staging result with existing-like data, and production recovery option. The Supabase guide explains that backup availability varies by project and plan; a Git revert does not restore deleted rows. Ask who can restore the database, how old the latest point is, and what happens to writes during recovery. If the app stores user uploads or external records, confirm those have their own backup or reconciliation path. A new feature without a migration still needs a check that existing user data remains readable after deployment.
- Record row-count or fixture checks before and after a staging migration.
- Identify any data source outside the application database.
- Hold a destructive change if recovery is unproven or ownership is missing.
Trace money and asynchronous work when they exist
For a Stripe Checkout flow, a success page is not the final state: Stripe's guidance requires a webhook path for reliable fulfillment and a function that tolerates repeated calls. Verify signed events, delayed or failed payment, one final entitlement, and the correct customer in a sandbox before live billing. If the app uses a background worker or scheduled tasks, start the actual development worker, trigger a test job, inspect the run result, and decide how failures are retried or surfaced in production. Canopy can keep local process output beside the project; the payment provider or job platform remains the authority for its own event and run state.
- Mark payment and worker gates 'not applicable' only when those capabilities are absent from the release.
- Keep test and live accounts, keys, and URLs distinct.
- Have a human owner for a paid customer who lacks access or a job that fails after launch.
Make a recorded go, hold, or cut decision
Collect the latest PR diff, named CI checks, running-app observations, access test, migration and backup result, payment or worker test if applicable, and unresolved risks. Put each item under an owner. A missing low-impact polish item may be cut from scope; a missing access rule, exposed credential, unreviewed data migration, or unexplained payment state calls for holding the relevant release. If you are not the technical reviewer, hand over the exact commit, run commands, observed results, and unknowns rather than asking an agent to certify itself. GitHub's branch rules can preserve the review process, but the release owner makes the final product decision for the verified version.
- State exactly what shipped, what was deferred, and who will monitor it.
- Revisit the sheet after any new commit or configuration change.
- Save the evidence for the next launch so the process improves rather than restarting from memory.
Copyable resources
Copyable release decision sheet
Use real observations and owners; never paste production keys or customer data into this record.
Product and release scope: [ ]
Repository / PR / latest commit / target environment: [ ]
Core journey success and failure observed by: [ ]
Cross-user access rule and denied request checked by: [ ]
Secret scan and credential exposure decision by: [ ]
Migration SQL, staging data, and recovery option checked by: [ ]
Payment and webhook test, if applicable, checked by: [ ]
Background job test, if applicable, checked by: [ ]
Named CI checks and final diff reviewed by: [ ]
Known gaps and customer impact: [ ]
Decision: GO / HOLD / CUT FEATURE
Decision owner and date: [ ]
Post-launch monitor and rollback contact: [ ] Frequently asked questions
Can an AI agent tell me my app is production-ready?
It can gather evidence and propose risks. A person still needs to verify the running behavior, technical controls, exact release version, and ownership of remaining risk.
Do I need every gate for a free prototype?
Apply the gates that match what the prototype exposes. A private demo with disposable data has a different scope from a public app holding customer records or taking payments; record that scope explicitly.
Does green CI mean I can launch?
It shows that configured checks passed for a commit. Confirm the user journey, access rules, data and payment paths, deployment target, and final reviewed diff separately.
What if a blocker cannot be fixed before the date?
Hold the release or remove and disable the affected feature with a verified scope change. Record the owner and recheck the final commit and deployed configuration.