Repo Janitor
Repo Janitor · repository maintenance

Know what needs attention.
See where to start.

Check a public repository for maintenance issues, inspect the evidence, and get a prioritized plan of what to improve first.

checks
27
areas
6
accounts needed
0

No account, no install. The repository is cloned to a temporary directory, read, and deleted when the scan finishes.

Run a real scan

Search GitHub or paste a repository URL, then add it to the list. Everything in the list is cloned and scanned by the Repo Janitor engine — no mock data.

Selected — 0 of 20

Nothing selected yet. Search above, or paste a repository URL.

Or try a known public repo — pick one, or compare two:

Type a name to search GitHub, or paste a repository URL.
  1. 01

    Inspect the findings

    See affected files, severity, and the reason behind each finding. Verify the context before making changes.

  2. 02

    Choose what to fix first

    Open the prioritized action plan with suggested steps and ways to verify a fix.

  3. 03

    Check your progress

    Scan again after a change. Add the CLI or GitHub Action when you want checks in your workflow.

The score describes repository maintenance signals, not proven security. Findings can need project-specific context; inspect the evidence and report false positives.

01the checks

27 checks, in six families

Explore checks for security, dependencies, configuration and maintenance. Each finding includes an explanation so you can assess it in your project's context.

false positives are bugs

  • Security

    05

    Credentials committed to the working tree or buried in history, dependencies with published advisories, dangerous constructs in your own code, and workflows that hand a stranger your token.

    • secrets
    • vulnerable-deps
    • insecure-code
    • workflow-security
    • supply-chain
  • Dependencies

    05

    Packages that stopped being maintained, runtimes past their end-of-life date, lockfiles that disagree with the manifest, and licenses that are incompatible with the one you ship under.

    • dependency-funeral
    • eol-runtime
    • license-risk
    • outdated-deps
    • lockfile-drift
  • CI & configuration

    04

    Whether the green badge means anything: silenced failures, tests no workflow runs, and two config files where one is silently ignored.

    • ci-health
    • config-conflict
    • dockerfile
    • project-hygiene
  • Documentation

    03

    Instructions that no longer work — a documented script that does not exist, a badge for a deleted workflow, links that have gone dead.

    • docs-drift
    • dead-links
    • broken-doc-links
  • Decay over time

    05

    The findings that appear on their own, with no commit behind them: branches nobody came back to, TODOs that aged into archaeology, files only one person has ever touched.

    • stale-branch
    • todo-debt
    • bus-factor
    • env-lifecycle
    • repo-bloat
  • Code weight

    05

    Exports nothing imports, blocks duplicated verbatim, commented-out code, forgotten debug statements and disabled tests.

    • dead-code
    • duplicate-code
    • commented-code
    • leftover-debug
    • skipped-tests
  • calibration

    Rules can misinterpret project context. Report incorrect findings so we can reproduce them and add regression tests.

    Report a false positive

02the maths

How the grade is worked out

A score out of 100: base penalties are −10 for a critical finding, −3 for a warning and −0.25 for an informational note. Repeated findings taper. In new scans, informational notes together subtract at most 10 points; warnings and critical findings remain uncapped.

0score100
F0–39
D40–59
C60–74
B75–89
A90–100
  • A

    A means the scan found little that costs points — not that the repo is perfect.

  • F

    F means enough weight of findings that the score fell below the last band.

worked examplescore.log
starting score100.0
3 × critical−30.0
5 × warning−15.0
final55D

Repeated findings have a reduced impact. All findings remain visible, even when resolving one does not change the rounded score.

03the fine print

What happens to your code

  1. 01

    Cloned to a temp dir

    The repository is cloned into a temporary directory on the server, read, and deleted when the scan finishes. History reports are reused from cache for 24 hours; expired entries are removed on later cache writes.

  2. 02

    The report stays in your browser

    The current scan report stays in this browser. Sharing stores a summary without file paths or snippets. Optional hosted AI sends finding titles and categories to OpenRouter with your opt-in. Recommendations are reused for 24 hours; expired cache entries and backups have separate retention.

  3. 03

    Two rows that cannot be joined

    Two rows per scan, in two tables that cannot be joined. One counts usage: a random browser id, the event, and the repository name — no score. The other records the result's shape — score, grade, main language, size band, findings per severity — with no name, no address and no browser id, so a score is never attached to a project. Never file paths, code, IP addresses or user agents.

not collected in anonymous usage analyticsfile pathssource codeip addressesuser agentsrepo name + scoreaccounts

04automation

Run it in CI instead

The same engine runs as a GitHub Action on every push: it fails the build below a grade you choose, uploads SARIF so findings appear in the Security tab, and comments the breakdown on the pull request.

  • Fails the build below a grade you choose
  • Uploads SARIF, so findings land in the Security tab
  • Comments the breakdown on the pull request
  • Keeps the health badge in your README current

Scans from CI also keep a health badge current — the one at the top of this project's own README.

.github/workflows/anti-rot.yml
on: [push, pull_request]

jobs:
  anti-rot:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: YpCIIIaK/repo-janitor@v1
        with:
          fail-on: B
          sarif-file: repo-anti-rot.sarif
anti-rotA · 93the badge stays current on every push