code-review — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited code-review (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
A disciplined, methodology-driven code review. The goal is not to leave many comments — it is to find the issues that matter, rank them honestly by impact, and propose a concrete fix for each. A review that flags one real SQL-injection beats a review that flags twenty style nits and misses the bug.
This skill is grounded in established practice:
studies) converge on the same point: the highest-value defects found in review are logic and correctness defects, not formatting. Read for what the code does before what it looks like.
OWASP Top 10 categories and the corresponding CWE weakness classes, so findings map to a recognized taxonomy instead of vibes.
complexity and the cost model (allocations, round-trips, I/O), not by micro-optimization folklore.
code-review guidelines: distinguish things that must change from preferences, label preferences as such, and never block a merge on style when a linter or formatter could settle it.
Activate this skill when the user:
of a change (run the relevant pass with extra depth, but still do a quick sweep of the others).
If the request is "write code" or "explain code," this is not the right skill. This skill evaluates existing code.
Before reading line by line, establish what you are reviewing. State these back to the user briefly so assumptions are visible:
radius) or a whole file (review all of it). For a diff, the surrounding unchanged code is context, not subject — but flag it if the change makes it wrong (e.g. a new caller breaks an old invariant).
security surface (e.g. Django ORM vs raw SQL, React vs server-rendered HTML).
library, infra-as-code? Does it touch the network, the filesystem, a database, user input, authentication, money, or PII? The surface dictates which passes matter most.
coverage for the touched code? "No tests for a behavior change" is itself a finding.
correct implementation of the wrong thing is still a finding.
If critical context is missing (e.g. you cannot tell whether input is trusted), say so explicitly and review for the worst plausible case.
Every finding gets exactly one severity. Be honest — inflating severity trains people to ignore you; deflating it lets real bugs ship.
| Severity | Meaning | Blocks merge? |
|---|---|---|
| Critical | Data loss, security vulnerability, crash, or corruption in normal use. | Yes |
| High | Wrong behavior / incorrect results for realistic inputs. | Yes |
| Medium | Performance or design risk that will bite under load or over time. | Usually |
| Low | Maintainability: unclear code, duplication, weak naming, missing docs. | No |
| Nit | Pure style / preference a formatter or linter could decide. | No |
Rules:
fix it, say so in one line and move on. Do not let nits dilute the signal.
problem, file it as the higher one and mention the other dimension.
behavior. "Could be a problem" is not a finding; "with n=0 this divides by zero" is.
Run the passes in this order. Earlier passes outrank later ones: a correctness bug is more important than a naming nit on the same line. Each pass is a checklist of concrete things to look for.
The highest-value pass. Read the changed logic and ask "for which input does this do the wrong thing?"
< vs <=,inclusive/exclusive ranges, empty collections, single-element collections.
Optionals unwrapped without a check; missing map keys; default-vs-missing.
ignored return/error values; partial failures that leave inconsistent state; cleanup that doesn't run on the error path (no finally/defer/with).
duplicate keys, the "happy path only" smell.
check-then-act (TOCTOU); non-atomic read-modify-write; assuming ordering between async tasks; deadlock / lock-ordering.
await (fire-and-forget promise); awaiting in aloop that should be parallel; unhandled promise rejection; mixing callback and promise styles; async function whose error path is silently dropped.
closed; growing caches/listeners never released; goroutines/threads that never exit.
== on floats; money in floats instead ofinteger minor units / decimal; integer overflow/truncation; rounding direction.
off-by-one on dates; comparing timestamps in different units (s vs ms).
wrong variable, fall-through, default branch missing.
Tag each finding with the relevant OWASP category and/or CWE id where it applies.
queries or shell commands from user input. (OWASP A03; CWE-89 SQLi, CWE-78 command injection, CWE-94 code injection.)
object id without verifying ownership); trusting a client-supplied role/flag. (OWASP A01; CWE-285, CWE-639.)
handling; credentials compared non-constant-time. (OWASP A07; CWE-287.)
secrets logged. (CWE-798 hardcoded credentials, CWE-532 secrets in logs.)
pickle/yaml.load/Java native deserializationof untrusted data; prototype pollution. (OWASP A08; CWE-502.)
(OWASP A10; CWE-918.)
normalization/containment. (CWE-22.)
innerHTML /dangerouslySetInnerHTML; unsanitized template output. (OWASP A03; CWE-79.)
input; mass assignment binding unexpected fields. (CWE-20, CWE-915.)
ECB mode; static IV; disabled TLS verification; predictable randomness for tokens. (OWASP A02; CWE-327, CWE-295, CWE-330.)
Justify each finding with complexity or a concrete cost (round-trips, bytes, allocations). Do not micro-optimize cold paths.
in/indexOf ona list inside a loop (use a set/map); repeated string concatenation in a loop.
building a full list when a generator/stream suffices; boxing in hot paths.
or event loop; missing batching; chatty APIs.
an entire dataset into memory; recursion without depth bound.
for queries with side effects.
abstraction; god object.
public interface.
signature, changed default, changed serialization format, narrowed accepted input. Flag breaking changes explicitly and ask about versioning.
with siblings? Are errors typed/actionable or stringly-typed?
A behavior change with no test is a finding.
error path, empty input, or the boundary the code handles.
shared global state between tests, randomness without a fixed seed.
private state and will break on refactor without catching real regressions; over-mocking that tests the mock.
blocks.
redefined.
single-letter names outside tight loops.
comments contradicting the code; missing doc on a non-obvious public API.
Before (or alongside) the passes, do a fast scan for instant blockers. Any hit is Critical until proven safe:
eval / exec / Function() / system() on anything derived from input.verify=False, rejectUnauthorized: false,InsecureSkipVerify: true).
except: pass, empty catch {})..env, credentials file, or key material in the diff.dangerouslySetInnerHTML / innerHTML with non-constant data.# TODO: add auth on a live route.Produce the review in this structure. Be specific, cite the line, propose the fix, and separate must-fix from nice-to-have.
One line, one of:
Critical/High.
Follow with a one-sentence rationale.
| ID | Location | Severity | Issue |
|---|---|---|---|
| C1 | path/file.py:42 | Critical | SQL injection via f-string query (CWE-89) |
| H1 | path/file.py:31 | High | Endpoint missing ownership check (IDOR) |
| M1 | path/file.py:55 | Medium | N+1 query inside the response loop |
Order by severity (Critical → Nit). Use stable IDs (C1, H1, M2, L1, N1) so the user can reference them.
For each finding, in severity order:
[C1] SQL injection — `path/file.py:42` — Critical (CWE-89, OWASP A03) Why it matters: theuser_idvalue comes straight from the request and is interpolated into the query string, so an attacker can read or drop tables. Fix: use a parameterized query. ``python # before cur.execute(f"SELECT * FROM orders WHERE user_id = {user_id}") # after cur.execute("SELECT * FROM orders WHERE user_id = %s", (user_id,))``
Every Critical/High must include the triggering condition and a concrete fix (code where feasible). Mediums should include a fix or clear direction. Lows/Nits can be one line each.
A short, genuine section acknowledging strengths — solid test coverage, a clean abstraction, a good edge-case already handled. This is not filler: it calibrates trust and signals you read the whole change, not just hunted for faults.
file:line. "Somewhere there's a bug" helps no one.PR; the diff under review is the subject.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.