Turn an AI-built app into a reviewer-ready ship packet: freeze the intent, map the architecture and permissions, run intent-vs-code gap analysis plus security and performance audits, build a test coverage map, and end with a GO, GO WITH FIXES, or NO-GO verdict. Use when an app was built mostly by an AI coding tool (vibe coding), when asked 'is this ready to ship', before handing an AI-built codebase to a reviewer, client, acquirer, or production, or when nobody on the team can explain what the generated code actually does.
./install.sh vibe-code-ship-checkname: "vibe_code_ship_check" description: "Turn an AI-built app into a reviewer-ready ship packet: freeze the intent, map the architecture and permissions, run intent-vs-code gap analysis plus security and performance audits, build a test coverage map, and end with a GO, GO WITH FIXES, or NO-GO verdict. Use when an app was built mostly by an AI coding tool (vibe coding), when asked 'is this ready to ship', before handing an AI-built codebase to a reviewer, client, acquirer, or production, or when nobody on the team can explain what the generated code actually does."
AI coding tools produce apps that run on the first try and read like senior work. That polish hides the gaps: routes with no authorization check, dependencies that do not exist, business rules the model guessed at, tests that cover the happy path only.
Research context, stated as the sources report it:
This skill closes the gap between "it runs" and "a reviewer can sign it." The output is a ship packet: eight short documents a reviewer can work through in one sitting, ending in a clear verdict. The workflow is harness-agnostic. It works the same whether the code came from a chat tool, an IDE assistant, an agent, or a mix.
Before reading code, write down what the app was supposed to do. Sources, in order of trust:
Write 01-intent.md: users and roles, the five to ten core jobs the app does, explicit non-goals, and the "must never" list (for example: a signed-out visitor must never read another user's data). If nobody can state the intent, that is the first finding. Stop and get it stated. Every later pass compares code against this document, not against vibes.
bash
python3 bin/ship_check.py <repo> --out ship-packet/00-scanner-draft.md
python3 bin/ship_check.py <repo> --format json --out ship-packet/scanner.json
The scanner reports pattern findings with file and line evidence: likely secrets, debug flags, permissive CORS, string-built SQL, outbound HTTP calls with no timeout, routes in a file with no authorization hint, manifests with no lockfile, env vars with no example file, plus a test map. Treat every finding as a review prompt, not a confirmed flaw. Confirm, fix, or dismiss each one with a written reason.
Caution: the scanner prints the evidence line, which can include the literal secret it found. Treat the draft as sensitive, share it only with the review team, and rotate any real secret it surfaces. Rotation is not optional: a secret that reached a repo is burned even if the repo is private.
Write 02-architecture.md following the standard design doc shape: Context and Scope, Goals and Non-Goals, Design Overview, Alternatives Considered, Cross-cutting Concerns. Keep it factual and code-derived:
If a component cannot be explained in plain sentences, flag it. Unexplainable code is a ship blocker until someone can explain it or it gets replaced.
Write 03-permission-map.md as a table. One row per route, endpoint, job, or admin action:
| Surface | Signed out | Signed in, own data | Signed in, other user data | Admin | Check location | |---|---|---|---|---|---| | GET /notes/:id | deny | allow | deny | allow | src/notes.py:41 |
Fill the "should be" values from the intent doc first, then read the code and record what the code actually does. Mark every mismatch. Pay special attention to:
Write 04-gap-analysis.md. Walk the intent doc job by job and record one of four states per job: matches intent, partial, missing, or extra behavior nobody asked for. Extra behavior deserves the same scrutiny as missing behavior: models add plausible features (export endpoints, password reset flows, public profiles) that were never requested and never reviewed. For business rules, test the boundaries a model tends to guess wrong: discounts, refunds, quotas, time windows, negative quantities, zero, repeated submission, and concurrent edits. Tenzai's testers found business logic and authorization were where vibe coded apps failed worst, because those rules live in the prompt's context, not in generic code patterns.
Write 05-security-audit.md, organized by the OWASP Top 10 (2021): A01 Broken Access Control, A02 Cryptographic Failures, A03 Injection, A04 Insecure Design, A05 Security Misconfiguration, A06 Vulnerable and Outdated Components, A07 Identification and Authentication Failures, A08 Software and Data Integrity Failures, A09 Security Logging and Monitoring Failures, A10 Server-Side Request Forgery. One section per category, even if the section says "checked, nothing found, method: X."
Add the AI-specific pass, which a normal audit misses:
Map the gate to NIST SP 800-218 (SSDF) terms if the reviewer asks: this audit is PW.7 (review and analyze code) and the next step's test map is PW.8 evidence (test executable code).
Write 06-performance.md. This is a read-and-reason pass, not a load test. Look for the patterns generated code repeats:
Each item gets: location, the load shape that makes it hurt, and the smallest fix. Do not invent timings. If a number matters, measure it with a real run and record the setup, or mark it unmeasured.
Write 07-test-map.md. Coverage percentage alone hides the point. Map tests to risk:
| Area | Tests exist | Tests assert behavior | Gap | |---|---|---|---| | Auth and permissions | yes | partial | no test for cross-user access | | Payments | yes | no, mocks assert nothing | full gap | | Core job 1 | yes | yes | edge cases only |
Use the scanner's per-directory test map as the starting grid, then read the tests. A test that calls the code and asserts nothing, or mocks the thing under test, counts as "exists, does not assert." List the three highest-risk untested areas and write the missing tests, or record them as accepted risk with a name next to the decision.
Collect the packet:
text
ship-packet/
00-scanner-draft.md
01-intent.md
02-architecture.md
03-permission-map.md
04-gap-analysis.md
05-security-audit.md
06-performance.md
07-test-map.md
08-verdict.md
08-verdict.md states one verdict:
A worked mini-packet is in references/worked-example.md. A blank packet scaffold is in assets/ship-packet-template.md; copy it and fill it in.
Every run produces the nine files above in a ship-packet/ directory in or next to the repo, plus a short summary in the reply: verdict, blocker count by severity, the top three risks in plain language, and the list of dependencies that failed verification (or "none"). Findings always carry file and line evidence. Anything the reviewer could not verify is listed as unverified, never smoothed over.
publisher key 2e43c913833850e6d80f939677e3de76e806d47785c0f1caaca90f9d18c98e1e
No ratings yet — be the first to rate it.