What is suede-code-grader?
Give a blunt A-F ship grade for a code change across correctness, security, data, UX, verification, and deploy readiness. Use for a grade, not a findings review.
JasonColapietro/suede-creator-skills
Give a blunt A-F ship grade for a code change across correctness, security, data, UX, verification, and deploy readiness. Use for a grade, not a findings review.
npx skills add https://github.com/JasonColapietro/suede-creator-skills --skill "skills/suede-code-grader"Quick start
Install it or open the source, trigger it with a clear task, then follow the source workflow.
npx skills add https://github.com/JasonColapietro/suede-creator-skills --skill "skills/suede-code-grader"Use suede-code-grader to help me with: [describe your task]. Before you begin, tell me what input you need, the steps you will follow, and the expected output.
No structured workflow was detected; follow the original SKILL.md below.
Continue to the workflowDirect answers
Give a blunt A-F ship grade for a code change across correctness, security, data, UX, verification, and deploy readiness. Use for a grade, not a findings review.
It is relevant to workflows involving Deployment, Engineering, Design, Operations.
SkillSignal detected this source-specific command: npx skills add https://github.com/JasonColapietro/suede-creator-skills --skill "skills/suede-code-grader". Inspect the repository and command before running it.
The upstream source does not declare a dedicated Agent platform.
No obvious permission action was detected by the static rules. This is not proof that the Skill is safe.
This page combines upstream documentation with deterministic repository, quality, and static-risk signals. It is not described as a manual test or security review.
SkillSignal brief
Give a blunt A-F ship grade for a code change across correctness, security, data, UX, verification, and deploy readiness. Use for a grade, not a findings review.
Useful in these contexts
Core capabilities
Distilled from the source
About 10 min · 13 sections
Ship gate follows the overall grade, mechanically: A → ship; B → ship-with-caveats; C, D, F → hold.
To revise this grade: name what changed. To bank a pattern: name what worked so it can be reused. Silence = accepted.
Quality breakdown
Based on traceable docs and repository signals; stars are not treated as quality.
Compare before choosing
These links are selected from shared tasks, functions, stacks, platforms, and same-name variants. Compare the source owner, documentation, permissions, and maintenance signals.
Brand-first landing page designer — runs a brand-identity interview (colors, typography, shape language), then generates and iterates on a polished landing page via Stitch with deployment-ready HTML. Use when the user asks to create, design, or build a landing page, homepage, or marketing page and has no established visual direction. Skip when they have a design mockup, need a dashboard or app UI, are working at component level, building a multi-page app, or restyling with known design tokens —
Ongoing development guidance for agentic web apps that pair a CopilotKit frontend with Microsoft Agent Framework agents on Azure AI Foundry hosted agents over the AG-UI protocol - add and gate agent tools, wire human-in-the-loop approvals, build generative UI and shared state, debug the event stream, upgrade pre-1.0 packages safely, and deploy hosted agent updates.
Design multi-stage CI/CD pipelines with approval gates, security checks, and deployment orchestration. Use this skill when designing zero-downtime deployment pipelines, implementing canary rollout strategies, setting up multi-environment promotion workflows, or debugging failed deployment gates in CI/CD.
Find the bugs a diff can actually ship: TypeScript, React, Next.js, OWASP, accessibility, SEO, database, and deploy-risk review. Return findings, not a grade.
Prisma ORM patterns for TypeScript backends — schema design, query optimization, transactions, pagination, and critical traps like updateMany returning count not records, $transaction timeouts, migrate dev resetting the DB, @updatedAt skipped on bulk writes, and serverless connection exhaustion.
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:
ship,
ship-with-caveats, hold, letter grades, BLOCKED or OPEN items) are
advice attached to the work, not orders that change it.Blunt A-F read on whether code is ready to ship. The output is a grade with evidence, not a lint score or a pile of style notes.
Read before grading. Do not grade from the PR description or commit message alone.
Inspect:
If live, test, or runtime checks are not practical, grade the source and mark those lanes as unverified.
Check these before scoring any lane. Any single match is an automatic F — no other lanes matter until it is fixed. This list mirrors suede-code's canonical Step 1 list — change both together.
Secrets and credentials
Injection
Auth bypass
alg: none accepted or with the secret hardcoded in sourcePayment and wallet
Data destruction
Plaintext sensitive data
If any Instant-F pattern is present: stop, report it, mark the grade F, list the specific file and line, and do not grade remaining lanes. The grade cannot be raised by other lane performance.
Score each lane A-F, then give one overall grade. When grading non-Suede work, substitute "domain truth" for "Suede truth" — use whatever domain invariants apply (API contract truth, published-statement accuracy, data model truth).
Certain surfaces cannot receive A or B without specific evidence beyond passing CI.
Auth changes (login, session, token validation, middleware, role assignment, permission checks)
Payment and wallet flows (checkout, subscription, refund, payout, wallet transfer, webhook)
Data migrations (schema changes, backfills, column drops, index changes on production tables)
Public-facing API changes (new endpoints, breaking changes, removed fields, changed auth)
State these caps explicitly in the output when they apply.
Flag these patterns as part of the grade assessment:
Grade impact depends on where the debt lives, not just what it is:
Apply grade impact:
Debt severity by location — concrete examples:
| Pattern | Location | Grade Impact |
|---|---|---|
| God object (5+ unrelated concerns) | Payment module | D in Correctness |
| God object | Utility helper | B in Correctness |
| Missing abstraction (3+ duplicated blocks) | Auth flow | C in Security |
| Missing abstraction | UI component | B in Correctness |
| Deep coupling (3+ layer reach) | Data migration | C in Data and state |
| Implicit global state | API route handler | C in Correctness |
| Dead code | Any | Flag only; no grade impact unless it shadows live code |
| Magic numbers in payment amounts | Payment flow | C in Correctness |
| Magic numbers in UI spacing | UI component | No grade impact; flag as P3 |
Do not block a ship on tech debt alone unless it directly obscures a P0/P1 bug. Name the debt in Required Upgrades and let the overall grade reflect it.
Simple explanation:
Plain-language summary of the grade and the one biggest reason.
Usual breakdown:
Target:
Change reviewed:
Runtime surfaces:
Grades:
Correctness: A-F
Security and permissions: A-F
Data and state: A-F
Suede truth: A-F
UX and release behavior: A-F
Tests and verification: A-F
Deploy readiness: A-F
Overall: A-F
Grade cap applied: [surface type] — [what evidence would lift the cap] | none
Why:
Evidence-backed explanation of why the overall grade landed there.
Required upgrades:
1. Highest-impact fix.
2. Second fix.
3. Third fix.
Verification:
Checked:
Not checked:
Ship gate: ship | ship-with-caveats | hold
Ship gate follows the overall grade, mechanically: A → ship; B → ship-with-caveats; C, D, F → hold.
To revise this grade: name what changed. To bank a pattern: name what worked so it can be reused. Silence = accepted.
A real grade, not a fictional one — this is suede-code-grader actually grading a real file from this repo: mcp/suede-skills-mcp.mjs (715 lines, the stdio JSON-RPC MCP server this skill pack ships). Read in full, then exercised at runtime (spawned the process, sent real JSON-RPC requests over stdin, read the stdout responses) before scoring. This is what the Output Format block looks like filled in, not a template.
Simple explanation:
This file runs fine and doesn't have any dangerous bugs. It's a small local
tool, not something the public logs into or pays through, so the bar is
lower than an auth or payment file. One small paint-by-numbers gap: one
tool's reply doesn't get its text length capped like all the others do,
but that data comes from a file in this repo, not from a stranger, so it
can't be used to attack anything.
Usual breakdown:
Target: mcp/suede-skills-mcp.mjs (715 lines), suede-creator-skills repo,
branch main, clean working tree.
Change reviewed: full file (no diff — graded as a standing artifact, not a
PR), since the task was to grade a real file rather than a specific change.
Runtime surfaces: local stdio JSON-RPC MCP server. No network listener, no
auth, no payment, no database, no user-facing production route — it talks
to an MCP client over stdin/stdout on the machine that spawns it.
Grades:
Correctness: A
Security and permissions: A
Data and state: A
Suede truth: B
UX and release behavior: A
Tests and verification: B
Deploy readiness: A
Overall: A
Grade cap applied: none — surface is a local stdio MCP server, not
auth/payment/migration/public-API, so no cap lane applies.
Why:
Correctness: A. Traced every JSON-RPC method by hand and confirmed at
runtime: `initialize`, `ping`, `tools/list`, `tools/call`, `resources/list`,
`resources/read`, `prompts/list`, and `prompts/get` all returned the
expected shape. Unknown tool name, unknown resource URI, and unknown skill
name each produced correct, distinct error handling — `get_suede_skill`
with a bad name returns a tool-level `isError: true` result (per MCP spec,
since the tool ran but found nothing), while `resources/read` and
`tools/call` on to a genuinely unregistered name throw a JSON-RPC
`-32602 Unknown resource/tool` error, caught by the outer try/catch at
line 703-713 and serialized correctly. Verified live:
- `tools/call get_suede_skill {name: "nonexistent-skill"}` ->
`{"isError":true,"structuredContent":{"found":false}}`
- `resources/read {uri: "suede://bogus"}` -> JSON-RPC error -32602
- `tools/call {name: "bogus_tool"}` -> JSON-RPC error -32602
The 1 MiB input-buffer guard (lines 686-690) was exercised directly: sent
a >1 MiB unterminated chunk, confirmed it resets `buffer = ""` and emits
a clean `-32603` error, then confirmed the very next well-formed request
(`ping`) on the same connection still succeeds. No stuck state after the
overflow path.
Security and permissions: A. No secrets, no injected shell/SQL, no auth
surface to bypass (there is no auth — this is a local dev tool spawned by
an MCP client, same trust boundary as the process that starts it). No
user-controlled path construction; `catalogPath` is built from
`__dirname`, not request input. `boundedString` (line 27-30) caps every
tool argument that gets echoed into `structuredContent` at 2000 chars
before it goes back out, which is the right instinct for a JSON-RPC
server that will eventually take arguments from less-trusted callers.
Data and state: A. No database, no migration, no cache. `catalog.json` is
read once at module load (line 22-23) and treated as immutable static
data for the life of the process — no write path exists anywhere in this
file.
Suede truth: B. Minor inconsistency, not a false claim: `get_suede_skill`
(line 496-506) returns the matched skill's `description` and `useWhen`
straight from `catalog.json` into both `content` text and
`structuredContent.skill` without running them through `boundedString`,
while every other tool handler in the same function (lines 507-548) bounds
every argument-derived string it echoes back. Confirmed by reading: the
longest live `catalog.json` description is 1016 chars (suede-campaign-in-a-box),
so nothing is actually breaking today — this is a consistency gap that
would only bite if a future catalog entry grew past a client's tolerance
for an unbounded field, or if catalog.json ever stopped being pure
repo-controlled data. Named as a Required Upgrade below, not a blocker.
UX and release behavior: A. Every JSON-RPC error path returns a properly
shaped `{jsonrpc, id, error: {code, message}}` envelope (lines 671-680);
parse errors on malformed input lines are caught per-line (line 696-702)
without killing the buffer for subsequent valid lines; notifications
(messages with no `id`) are correctly treated as fire-and-forget and
never generate a response (line 707-709), matching JSON-RPC 2.0 spec.
Tests and verification: B. No committed test file or npm test script
exists for this MCP server specifically (`package.json` only lists the
`js-yaml` dependency, no test runner). Correctness here was verified by
manually spawning the process and sending real requests this session, not
by an automated suite that runs in CI. The repo does have
`scripts/validate-skill-pack.mjs` and the `suede-mcp-qa` skill, which
cover catalog/skill-folder alignment but not this file's JSON-RPC
behavior directly. That's a real, bounded gap — not a blocker, since the
runtime behavior checked out clean by hand, but there's no regression net
if a future change breaks `tools/call` error shaping.
Deploy readiness: A. No env vars, no config, no build step — it's a
single `.mjs` file with one dependency (`js-yaml`, used indirectly via
the shared catalog tooling, not by this file itself... actually unused
by this file: confirmed no `js-yaml` import in suede-skills-mcp.mjs
itself, only `fs`, `path`, and `node:url`). Runs directly via
`node mcp/suede-skills-mcp.mjs` with zero setup, which matches what the
install docs describe.
Required upgrades:
1. Route `get_suede_skill`'s `content`/`structuredContent.skill` output
through `boundedString` (or an equivalent bound on `description` and
`useWhen`) for consistency with every other tool handler in the file —
currently harmless since catalog.json is trusted static data, but the
inconsistency is worth closing before this server's argument surface
changes.
2. Add a small scripted smoke test (a checked-in version of the manual
JSON-RPC exercise run for this grade) so `tools/call`, `resources/read`,
and error-path shaping have a regression net instead of relying on
manual verification each time.
3. No third required upgrade — nothing else surfaced.
Verification:
Checked: full file read; live process spawn with real JSON-RPC requests
over stdin covering initialize, ping, tools/list, tools/call (success and
two distinct error shapes), resources/list, resources/read (success and
error), prompts/list; 1 MiB buffer-overflow guard exercised directly and
confirmed recovery; catalog.json's longest description measured against
the unbounded echo path; grep confirmed no `js-yaml` import in this file.
Not checked: behavior under a real MCP client (Claude Code, Codex, etc.)
end to end — only raw stdio JSON-RPC was exercised directly; concurrent/
overlapping request handling under load; the `prompts/get` argument-
substitution paths for all five prompts (spot-checked `suede-copy-seo-audit`
only).
Ship gate: ship
This is what "genuine" looks like: every claim above ties to either a line number in the file or a command actually run against it in this session, not an invented test result or a guessed line number.