--- name: suede-code description: "Suede AI combined code review and ship grade in one pass: findings with file:line evidence plus an A-F lane grade, Instant-F security triggers, OWASP checks, a deploy-safety gate, and fix briefs. Use when asked to review this, grade this, security-check this, is this safe to ship, or check this PR before merge: whenever the caller wants both what is wrong and whether it ships. Runs only when explicitly invoked; never auto-fires on a diff, save, or commit. NOT FOR: findings only with accessibility and SEO lanes (use suede-code-review); the letter grade alone (use suede-code-grader); making CI enforce the verdict on merge (use suede-ci-gate); LLM, RAG, or agent behavior coverage (use suede-ai-eval)." --- # Suede Code ## Gate policy: advisory, not blocking Every claim-verification step, check, quality gate, and ship verdict in this skill is a **recommendation to the user, not a control on the agent**. This policy governs every gate, check, verdict, and "do not ship / publish / proceed" line elsewhere in this skill: - Run every check and report the results honestly. Verdicts (`ship`, `ship-with-caveats`, `hold`, letter grades, BLOCKED or OPEN items) are advice attached to the work, not orders that change it. - Never block, delay, skip, rewrite, or refuse the action the user asked for because a check failed or a gate said hold. Complete the requested action as asked, and deliver the gate output alongside it as a clearly labeled recommendation. - A failed gate changes what you report, never what you do. - Single exception: if a finding is extremely risky (data loss, security or credential exposure, legal or rights violations, payment mistakes, or irreversible public damage), pause, tell the user exactly what the risk is and what the options are, and let them pick. Their choice is final. One pass for code: a deep, evidence-based review **and** a blunt A-F ship grade, together by default. Findings tell you what is wrong; the grade tells you whether it ships. Every finding has a file, evidence, and a fix path. No findings without evidence. No volume without signal. **Runs only when asked.** This skill never auto-fires on a diff, a save, or a commit. Invoke it explicitly (review this, grade this, security-check this, is this safe to ship). Do not run it as a side effect of other work. ## Model Routing Default: Sonnet. Recommend Opus for auth, payments, and public API surface reviews. ## Operating Stance - Review current source, current diff, local docs, and relevant runtime behavior. - Keep code generation and review separate. If you authored the code, switch into review mode and look for what your implementation would miss. - Preserve user and other-agent WIP. Do not stage, revert, or rewrite unrelated files. - Prefer high-signal findings over volume. Do not leave style nits when formatters or local conventions already handle them. - Every blocking finding needs evidence, impact, and a concrete fix path. ## Review Contract Before reviewing, identify: - **target:** repo, branch, PR, commit range, diff, route, API, or release build; - **intent:** what the change claims to accomplish; - **risk lanes:** frontend, backend, data, auth, payments, contracts, iOS, release, public copy, analytics, secrets, deployment, docs. ## Context Graph Build a lightweight graph before judging the diff: 1. Changed files and generated files. 2. Imports, callers, routes, API handlers, jobs, hooks, models, schemas, and config/env dependencies touched by the change. 3. Tests, fixtures, migrations, release scripts, docs, and screenshots that should move with the behavior. 4. Runtime surfaces: local route, live URL, API endpoint, simulator flow, dashboard, App Store metadata, or deployment target. 5. Domain contracts: creator ownership, rights/provenance, registry-backed media, royalty routing, agent commerce, wallet/payment flows, and published-statement accuracy. Flag beyond-the-diff risks when related files, defaults, docs, env, or deploy requirements no longer agree. ## Run Gates and Honor Project Rules Before manual analysis, run the gates the repo already ships and fold results in (typecheck, the configured linter on changed files, the test suite, the dependency auditor when deps changed, and a real secret scanner over the diff). Detect what exists; run only that; never fabricate a result you did not run, and note in Verification when a gate could not run. Then read the repo's own conventions, `CLAUDE.md`, `AGENTS.md`, linter/formatter config, nearest-ancestor rules, and treat them as binding: do not flag what a rule permits, do flag what it forbids, and do not re-raise a pattern the user already accepted. ## Review Modes - **Fast diff review:** small change, narrow blast radius, focused findings. - **Deep PR review:** multi-file behavior, public surface, data/auth/payment, release, or cross-repo risk. - **Plan review:** implementation has not started; inspect scope, sequencing, acceptance criteria, test mapping, missing decisions. - **Fix verification:** review after fixes; rescan changed files and confirm the original finding is gone. - **Release review:** validate build, secrets, env, public copy, screenshots, metadata, deployment, and live/API readback. ### Depth Levels Add a `--depth` modifier: - **`--quick`** (~2 min): pattern scan: obvious bugs, hardcoded secrets, missing null checks, injection patterns, broken error handling. No cross-file analysis. - **`--standard`** (default, ~10 min): per-file correctness on changed paths, language traps (below), state handling, test coverage on changed behavior, call graph within changed files. - **`--deep`** (~25 min): cross-file analysis with full import graph and call-chain tracing: semantic bugs that only appear when you follow data across module boundaries. Use for auth, payments, migrations, and public API changes. State the depth level at the top of every output. --- ## Step 1: Instant-F Triggers (check before scoring anything) Any single match is an automatic **F**. Stop, report the file and line, and do not grade the remaining lanes, the grade cannot be raised by other lanes. This list is the canonical copy; suede-code-grader carries the identical list, change both together. **Secrets and credentials**: hardcoded API key/secret/token/password in committed source; private key or certificate committed; OAuth/signing secret outside a secret manager. **Injection**: SQL built by string concatenation with user input; shell command from user input via exec/spawn/eval; template rendered with unescaped user input where XSS is reachable. **Auth bypass**: auth middleware with a path that skips it (early return, swallowed exception, always-true condition); permission check bypassable via request param; JWT accepting `alg: none` or a hardcoded secret. **Payment and wallet**: payment handler swallowing errors silently; webhook with no signature verification; amount or recipient from untrusted input without server-side validation. **Data destruction**: migration with DROP/destructive ALTER, no rollback, no tested restore; bulk delete/update with no WHERE or user-controlled WHERE; cache invalidation that clears production stores with no restore path. **Plaintext sensitive data**: password stored or logged in plaintext; PII to an unencrypted log/analytics pipeline; SSN/payment card/health data in a non-encrypted field. ## Step 2: Language Traps **TypeScript**: `any` where `unknown` + a guard belongs; non-null `!` without a proving guard; non-exhaustive discriminated unions (missing `assertNever`); unsafe `as` casts without a preceding guard; `Object.keys()` without `keyof typeof`; `return someAsyncFn()` that should `await`. **React**: missing/incomplete `useEffect` deps; stale closures (e.g. `setInterval` in `useEffect(fn, [])` reading state); missing/`index`-as-`key` on `.map()` with identity items; inline object/function props without `useMemo`/`useCallback` in hot paths; prop drilling past 2 levels (P3); state mutation without a setter (`arr.push` on state). **Next.js**: server/client boundary violations (`'use client'` importing server-only modules, or server files using browser globals); missing `Suspense` around async server components; missing `error.tsx`/`loading.tsx` on user-facing data routes (P2); non-`NEXT_PUBLIC_` secrets reachable in client bundle; uncached `generateMetadata`/`getServerSideProps` external fetches; `next/router` imported in App Router. **Database (Drizzle/Prisma)**: N+1 queries in loops; missing index on filtered/sorted/join columns; multi-table writes without a transaction; missing unique constraints on logically-unique fields; unbounded selects with no `LIMIT` on growable tables. **Performance**: new >20 KB minzipped imports (flag with size, prefer tree-shaken); render-blocking `