Skill
Pre-merge / pre-handoff verification of any Asset Rise code change. Use before declaring work done, before merging to main, and before handing a worktree to review. Full gate command sequence, diff-review checklist, and PASS/FAIL verdict format.
Playbook (mirrored from disk)
QA Gate — Verify Before Handing Off
Run from the checkout under review (main or a worktree — adjust paths accordingly).
Gate sequence (all must pass)
cd apps/api && npx tsc -p tsconfig.json # api typecheck (noEmit in tsconfig)
cd ../web && npx tsc -p tsconfig.app.json --noEmit # web typecheck
cd ../.. && npm test # api vitest suite
npm run build # web vite build + api tscGOTCHA: bare npx tsc --noEmit in apps/web validates NOTHING (tsconfig.json is a references stub) and vite build does not typecheck — the -p tsconfig.app.json form is mandatory (a missing import shipped a prod crash this way).
Diff review checklist
- New dependencies → STOP, policy approval required first (supply-chain rule: exact pin two versions behind latest, no
as anyadditions — reject; cast to shared row interfaces instead.console.logdebug noise left behind (tagged[domain]logs are the convention; untagged spam is not).- Privileged mutations missing
audit()/notify(). - Migrations: every statement idempotent? numbering =
max(NNN)+1from a directory listing? (they re-run on every api boot). - Permission mirror: new
sc_permissionsrows ↔apps/web/src/lib/auth/permissions.tsupdated in lockstep. - Hebrew on all user-facing strings and TRPCError messages; toast on every user action.
.jsextensions on new api relative imports.
UI changes
No web test suite exists — NEVER claim “tests passed” for apps/web. Visual verification = build + deploy + look at the served result (curl the route, screenshot if possible). If you cannot see it, say so explicitly.
Verdict format
QA GATE: PASS | FAIL
Gates: api-tsc OK | web-tsc OK | tests N/N | build OK
Blocking (FAIL only):
1. <file>:<line> — <issue> — <required fix>
Non-blocking notes: ...
Any gate failure or blocking checklist item = FAIL. Don’t soften: blocked is blocked.