How the Denofy scanner works
What the scanner checks, how a scan becomes a grade from A to F, what it cannot do — and 14 demo packages that show every grade.
Updated 17 Oct 2026 3 min read
Every version published on Denofy runs through the same automated scanner before anyone can install it. The result is public on the package page under Verification. It is an automated analysis, not a guarantee: it finds known patterns, it does not prove that a package is harmless.
What the scanner checks#
- Structure — is there a valid main file (
SKILL.md, rule, subagent …) with the frontmatter the tools need? Are paths safe and the package within the size limits? - Compatibility — can the package be installed for every tool it declares?
- Security patterns — 25 pattern rules over every file: remote scripts piped
into a shell, access to SSH keys or credential files, dynamic
eval, raw IP addresses, invisible Unicode, prompt-injection phrases and more. Each finding is weighed by its context: the samecurl … | shcounts more in a script than in prose, and only as information when the text says "never do this". - License — does the declared license match the LICENSE file and the repository?
- Changes — which risks are new since the previous version?
The scanner reports what it found as "the scanner found n patterns". A pattern is a reason to read the code, not a verdict.
From findings to a grade#
Every version starts at 100 points; findings, license problems and structure errors deduct points, and some rules cap the grade. Security and quality grades use the same scale:
| Grade | Points |
|---|---|
| A | ≥ 90 |
| B | ≥ 80 |
| C | ≥ 70 |
| D | ≥ 60 |
| F | below 60 |
A critical finding always means F, a high finding C at most, and a finding the author allowed in
denofy.yml B at most. Every rule and its points are on the
security methodology page.
The scanner in action: 14 demo packages#
These packages are inert test cases (reserved .invalid domains, documentation-only IP
addresses, scripts that are never executed). They are unlisted — not in search or rankings —
and cannot be installed: the package page shows "Blocked: critical findings" instead of an
install command, and the download API and the CLI refuse them. The same applies to every package
graded F or with a critical finding. Open one to see its full report:
| Demo package | Grade | Status |
|---|---|---|
| Clean packagescanner-demo-01-clean | 100/100 | Verified |
| Link to an unknown domainscanner-demo-02-unknown-link | 99/100 | Verified |
| No licensescanner-demo-03-no-license | 89/100 | Warning |
| sudo in the instructionsscanner-demo-04-sudo-in-docs | 88/100 | Warning |
| Finding allowed in denofy.ymlscanner-demo-05-allowed-exception | 95/100 | Warning |
| Two medium findingsscanner-demo-06-two-medium | 68/100 | Warning |
| Reference to the SSH folderscanner-demo-07-ssh-reference | 75/100 | Warning |
| URL with a raw IP addressscanner-demo-08-raw-ip | 75/100 | Warning |
| Dynamic eval in a scriptscanner-demo-09-eval | 74/100 | Warning |
| Two high findingsscanner-demo-10-two-high | 49/100 | Warning |
| Broken structurescanner-demo-11-broken-structure | 80/100 | Failed |
| Remote script piped into a shellscanner-demo-12-pipe-to-shell | 38/100 | Failed |
| Invisible Unicodescanner-demo-13-invisible-unicode | 75/100 | Warning |
| Several problems at oncescanner-demo-14-mixed | 0/100 | Warning |
What the scanner cannot do#
- It does not run the package and cannot judge whether instructions make sense.
- New attack patterns are only found once a rule exists for them.
- A clean scan of one version says nothing about the next one; check the changes when you update.
Disagree with a result?#
Every finding has a Dispute this finding link and every grade a Dispute this grade link. They open the contact form with the package, the version and the rule ID (or the grade) in the subject. A finding means the files match a pattern associated with a risk — not that the author intended harm. Moderators can approve a version manually; rule fixes are re-run on all packages.