Security30% weight
88Good
Quality25% weight
88Good
Hygiene25% weight
65Fair
Community20% weight
79Good
History (8 scans)
Click a series to toggle · click a dot to jump to that scanLatest: Jun 5
SecurityiSupply-chain + code security posture. Weighted: 40% OpenSSF Scorecard (CI hardening, branch protection, signed releases, fuzzing…), 40% Semgrep p/security-audit findings, 20% known dependency CVEs from Trivy.
88/ 100 · weight 30%
- OpenSSF ScorecardiOpenSSF Scorecard runs ~18 checks (Branch-Protection, Code-Review, CI-Tests, Dangerous-Workflow, Dependency-Update-Tool, Fuzzing, License, Maintained, Pinned-Dependencies, SAST, Security-Policy, Signed-Releases, Token-Permissions, Vulnerabilities, Webhooks, etc.). We take the aggregate 0–10, multiply by 10 to get 0–100.Aggregate across ~18 supply-chain checks71
- Semgrep p/security-auditiSemgrep runs the p/security-audit ruleset (~150 rules). Each finding is weighted by severity (ERROR×3, WARNING×2, INFO×1), then divided by (LoC/1000+1) so a large repo isn't penalised for the same absolute count. 0 findings = 100; the score drops as density rises.LoC-normalised SAST finding density100
- Dependency CVEs (Trivy)iTrivy scans lockfiles + manifests for known CVEs. We start at 100 and subtract: Critical −25, High −10, Medium −3, Low −1. 0 vulns = 100.Critical/High/Medium/Low penalty100
QualityiInternal code quality signals. Weighted: 30% complexity, 25% lint density, 20% duplication, 15% test signal (we look for tests + CI runner + coverage), 10% file size (no mega-files >1000 LoC).
88/ 100 · weight 25%
- Cyclomatic complexity (lizard)iLizard measures cyclomatic complexity per function (CCN = decision points + 1). We take the repo-wide average. Avg ≤5 = 100, then drops linearly until avg ≥15 = 0. Lower is more readable and easier to test.Avg complexity: 1.96100
- Lint densityiWe run the language-native linter on detected languages (ruff for Python, eslint for JS/TS, golangci-lint for Go, etc.) and count issues per 1000 lines. 0 issues = 100. The score drops as issue density rises.0 issues across detected languages100
- Duplication (jscpd)ijscpd detects copy-paste blocks across the codebase using token-level matching (default: ≥50 tokens, ≥5 lines). We exclude node_modules, dist, build, lockfiles, fixtures and *.min.js. 0% duplication = 100; each 1% costs 5 points.1.44% duplicated93
- Test signaliWe don't execute tests (sandbox rule). Instead we score 4 signals: tests directory present (40), CI invokes a test runner (30), coverage badge in README (20), coverage config file at root (10). Total /100. Breakdown below.See checklist below — we don't run tests, we look for them40
- File sizeiCount of source files exceeding 1000 lines (per cloc, which excludes blanks and comments). Mega-files are hard to test, review, and modify safely. 0 = 100; each mega-file costs 5 points.4 files over 1000 LoC80
Test signal breakdown
- ✓Tests directory or test files presentiA tests/test/__tests__/spec directory exists at root or in a monorepo workspace. We don't run them — we just look for the structure.+40
- ✗CI invokes a test runneriA CI workflow file mentions pytest, jest, vitest, mocha, go test, cargo test, mvn test, rspec, or similar. Tests aren't useful if CI doesn't run them.0 / 30
- ✗Coverage badge in READMEiREADME contains a codecov.io, coveralls.io, or shields.io coverage badge URL. Public coverage signals commitment to quality.0 / 20
- ✗codecov.yml / coverage.xml presentiA codecov.yml, .codecov.yml, or coverage.xml file exists at the root. Indicates coverage is actively measured, not just badged.0 / 10
HygieneiOSS housekeeping checklist — 13 binary items totaling 100 points (README, LICENSE, CONTRIBUTING, CoC, SECURITY, CI, PR-triggered CI, tests dir, .gitignore, GH description, GH topics, recent commit). Pure discipline; the easiest dimension to max.
65/ 100 · weight 25%
Hygiene checklist
- ✓README.md exists & is non-trivial (>300 chars)iA README at the repo root with at least 300 characters. README.rst and README.markdown also count.+15
- ✓LICENSE fileiA LICENSE, LICENSE.md, or COPYING file at the root. Required for anyone to legally use your code.+15
- ✓LICENSE is OSI-approvediLicense SPDX matches an OSI-approved one (MIT, Apache-2.0, BSD-3-Clause, GPL-3.0, MPL-2.0, etc.). Detected from GitHub's license API and from the LICENSE body.+5
- ✗CONTRIBUTING guideiCONTRIBUTING.md / CONTRIBUTING.rst at the root (or .github/). Tells outsiders how to file issues and submit PRs.0 / 8
- ✗CODE_OF_CONDUCTiCODE_OF_CONDUCT.md at the root or in .github/. Sets community behavior norms.0 / 5
- ✗SECURITY.mdiSECURITY.md at the root or in .github/. Tells security researchers how to report vulnerabilities responsibly.0 / 7
- ✗CI configured (.github/workflows or .gitlab-ci)iAt least one workflow file in .github/workflows/ (or a .gitlab-ci.yml). Without CI, code lands unverified.0 / 10
- ✗CI runs on pull_requestiAt least one workflow triggers on `pull_request`. Otherwise CI only runs after merge, which defeats the point.0 / 5
- ✓Tests directory presentiA tests/, test/, __tests__, or spec/ directory at root — or in any of apps/*, packages/*, services/*, libs/*, modules/*, crates/* for monorepos.+10
- ✓.gitignorei.gitignore at the root. Cheap signal that the repo is curated rather than dumped.+3
- ✓GitHub description setiThe one-line description shown under the repo name on GitHub. Helps discoverability.+5
- ✓GitHub topics setiAt least one topic (tag) configured on the repo. Drives GitHub's category browse and search.+5
- ✓Last commit within 365 daysiRepo's `pushed_at` is within the last year. Older = likely abandoned.+7
CommunityiHealth of the community around the project. Weighted: 35% activity (recency + commit volume), 25% contributors (distinct authors in 365d), 20% popularity (star count, log-scaled), 20% responsiveness (median issue first-response time).
79/ 100 · weight 20%
- ActivityiCombines `pushed_at` recency with commit volume. Last commit >365d ago = 0. Last commit 181–365d = 30. Within 180d: 40 + 2×commits-in-90d, capped at 100.Recency + commits in last 90 days40
- ContributorsiDistinct authors with at least one commit in the last 365 days. Score = log₂(count + 1) × 25, capped at 100. So 1=25, 3=50, 7=75, 15=100. Logarithmic so a project doesn't need hundreds of contributors to score well.Log₂ of distinct authors in last 365 days100
- PopularityiScore = log₁₀(stars + 1) × 25, capped at 100. So 100 stars = 50, 1000 stars = 75, 10000 stars = 100. Logarithmic so very early projects aren't punished, but a perfect score requires real adoption.Log₁₀ of stars (17523)100
- ResponsivenessiMedian hours from issue creation to first non-author comment, sampled from up to 20 issues opened in the last 90 days. <24h = 100, <72h = 80, <168h (1wk) = 60, <720h (30d) = 30, else 0. No issues in 90d = neutral 70.Median time-to-first-response on issues, last 90 days100
Scan inputs
Total lines of code23,821
Languages detectedPython, Markdown, reStructuredText, TOML, YAML, SVG, Text, JSON, INI, Bourne Shell
Stars17,523
Files over 1000 LoC4
Findings (5)
hygiene5 findings
- infoMissing hygiene check: code_of_conduct
- infoMissing hygiene check: contributing
- infoMissing hygiene check: security_md
- infoMissing hygiene check: ci_present
- infoMissing hygiene check: ci_pr_trigger
Reproducibility
Formula version
v1.0Branch scannedmain
Commit SHAc48021040a50…
Last push to repoJun 4, 2026, 4:22 PM (4mo ago)
CompletedJun 5, 2026, 10:18 AM
Tool versions[email protected] · [email protected] · [email protected] · [email protected] · [email protected] · [email protected] · [email protected]
Embed in your README
Always shows the latest grade[](https://stackhealth.dev/r/pallets/click)Tip: anyone can score a repo by swapping github.com → stackhealth.dev in the URL.