Is it vulnerable?
Catch removed protections, exposed secrets, unsafe data flows, and dependency risks.
Open source · for teams using AI coding agents
Skylos is an open-source (Apache-2.0) static analysis CLI and pull request check for Python codebases. It finds dead code, security issues, and secrets.
Agents can make unfinished work look done: a skipped test, a loosened CI step, an answer hard-coded to match the test. skylos done runs your tests, compares the branch with main, and fails the check when it finds those shortcuts.
On your machine
Install Skylos, check out the agent's branch, and run skylos done. It runs your tests, compares the branch with main, and prints a receipt with the result of each check.
The agent's change (git diff main)
--- a/shop/pricing.py+++ b/shop/pricing.py-PERCENT_OFF = {"SAVE10": 10}+PERCENT_OFF = {"SAVE10": 10, "SAVE20": 20} def apply_discount(total: float, code: str) -> float:- percent = PERCENT_OFF.get(code, 0)+ percent = PERCENT_OFF[code] return round(total * (100 - percent) / 100, 2)--- a/tests/test_pricing.py+++ b/tests/test_pricing.py assert apply_discount(100.0, "SAVE10") == 90.0 +def test_save20_takes_twenty_percent_off():+ assert apply_discount(100.0, "SAVE20") == 80.0+++@pytest.mark.skip(reason="flaky") def test_unknown_code_keeps_total(): assert apply_discount(100.0, "BOGUS") == 100.0skylos done --base main
$ skylos done --base mainSkylos done · base 8da0a2b (merge base) · head d0ff52aUNFINISHED Tests pass when Skylos runs them: Earlier required checks failed or were incompleteFAIL No tests deleted, skipped or weakened: 1 test change(s) weaken what the tests check tests/test_pricing.py:15 SKY-A111 test_unknown_code_keeps_total now skips or expects failure (skip) tests/test_pricing.py:14 SKY-A101 (advice) Test was skipped or xfailed in this diff Fix: Put back the removed or skipped tests and the original assertions and settings.PASS Skylos settings and hooks left alone: Skylos settings, hooks and protected paths unchangedPASS No secrets added: No secrets addedPASS Every package and import is real: Every added import and package resolvesWARN Tests check the changed lines: Earlier required checks failed or were incompletePASS Code doesn't special-case the tests: No code special-cases the tests (1 changed file(s) read)PASS Linters, type checkers, scanners and CI not silenced: No linter, type-checker, scanner or CI settings weakenedVerdict: FAIL (Tests pass when Skylos runs them, No tests deleted, skipped or weakened)Receipt: .skylos/receipts/d0ff52a8ddaa-8da0a2b2fb37.json$ echo $?1Recorded output from Skylos 4.47.1 on a small example repository. Nothing runs or uploads in your browser.
Five checks fail the run by default. Three only add advice to the receipt, so a reviewer can decide.
Start on your machine. Add the check to CI so every pull request gets it. Use Cloud when a team needs merge blocking and one policy.
Free, no account. Compares your branch with main and runs your tests.
Writes .github/workflows/skylos.yml. Commit it, and each pull request gets a Skylos check, with a Skylos Done job when Skylos finds a pytest project or a test_command. No API key or secret is needed.
Connect a repository with the Skylos GitHub App, and one click opens a pull request that adds the Skylos workflow; it runs skylos done on pull requests into your default branch. Merge it, then require the Skylos check in GitHub. Available on the Free plan.
Each check passes or fails with evidence, the way CI does, and no model decides a block. The benchmark write-up publishes the method, the data, the honest runs it blocked, and what it missed.
Also in the CLI
The same install scans a whole repository, on your machine and without an account.
Catch removed protections, exposed secrets, unsafe data flows, and dependency risks.
Find dead code with framework-aware analysis for real applications and tests.
Review diffs for missing validation, invented APIs, and regressions before merge.
from flask import request def search_users(conn): name = request.args.get("name") query = f"SELECT * FROM users WHERE name = '{name}'" return conn.execute(query).fetchall()The flagged line is highlighted.
Possible SQL injection: tainted or string-built query.
10 Skylos-assisted dead-code cleanup PRs merged into the default branch in 9 open-source projects.
Inspect the evidenceSkylos Cloud keeps a team's results, policy, and history in one place. The pull request checks still run in your own GitHub Actions with the open-source CLI.
Run the checks yourself at no cost. Add Cloud when a team needs shared history and policy.
For developers checking branches locally or in CI.
$0
Free includes 1 project and 10 stored scans. Any credit pack unlocks the Workspace tier with 10 projects, 500 stored scans per project, and team features. Workspace then stays on for good: there are no seats or subscriptions, and later packs only add credits.
$9 / 50 credits
Your first workspace starts with a 7-day Workspace trial and 50 credits.
AI reviewers read the diff and comment on it. skylos done runs your tests and compares your test files, test settings, and CI steps with main. Each check passes or fails with evidence, and no model decides the block. They answer different questions, so you can run both.
Only the checks listed under "What blocks by default" fail the run; the others add advice to the receipt. You can set any check to block, advise, or off in [tool.skylos.done.checks] in pyproject.toml on your main branch. The benchmark write-up lists the honest runs it blocked and what it missed.
A CLI scan, including skylos done, never sends your source code anywhere and calls no AI model; dependency and import checks look up package names and versions in public registries and OSV. Cloud receives findings and short code snippets only when you upload with --upload or connect the Skylos GitHub App. A GitHub App scan copies one commit into a temporary sandbox that is deleted when the scan ends.
skylos done runs pytest automatically and reads Jest, Vitest, Mocha, node:test, and Playwright Test files. For other test runners, set test_command in [tool.skylos.done]. The wider scanner covers more languages, with depth that varies by language; see the next question.
Dead code: Python, TypeScript/JavaScript, Java, Go, PHP, Rust, Dart, Kotlin, C#, and C++ (unused file-local functions only). Security: Python, TypeScript/JavaScript, Java, Go, PHP, Rust, Dart, C#, and Shell, plus GitHub Actions, GitLab CI, and Dockerfiles. Python, TypeScript/JavaScript, and Java get the deepest analysis. Go needs the skylos-go engine, which ships in the Docker image and GitHub Action but not in the PyPI package, and Dart needs an extra parser.
No. It looks for specific shortcuts in tests, test settings, CI, and code. It can't prove code is correct; it tells you when the evidence that a branch is done is missing.
Yes. The open-source CLI, including skylos done and the GitHub Actions workflow, runs without a login. Skylos Cloud has a Free plan with a pass/fail check on pull requests; Workspace adds shared history, policy, and team review.
Compute-heavy actions: scan comparisons, AI fix PRs, AI issue triage, MCP remediation, and compliance reports. Scan uploads, Cloud scans of your GitHub repositories, PR checks, and the merge gate never use credits. Deep scans do. MCP scan tools run on your machine and don't use credits. They need a project API key, except the dead-code analyze tool, which works without one for 5 calls a day. Your first workspace starts with a 7-day Workspace trial and 50 credits.