slopaudit 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. slopaudit-1.0.0/.gitignore +12 -0
  2. slopaudit-1.0.0/CHANGELOG.md +113 -0
  3. slopaudit-1.0.0/LICENSE +21 -0
  4. slopaudit-1.0.0/PKG-INFO +273 -0
  5. slopaudit-1.0.0/README.md +238 -0
  6. slopaudit-1.0.0/action.yml +85 -0
  7. slopaudit-1.0.0/benchmarks/compare.py +261 -0
  8. slopaudit-1.0.0/benchmarks/corpus/safe/safe_abstract.py +11 -0
  9. slopaudit-1.0.0/benchmarks/corpus/safe/safe_add_tool.py +8 -0
  10. slopaudit-1.0.0/benchmarks/corpus/safe/safe_allowlist_command.py +12 -0
  11. slopaudit-1.0.0/benchmarks/corpus/safe/safe_confirmed_delete.py +10 -0
  12. slopaudit-1.0.0/benchmarks/corpus/safe/safe_constant_eval.py +3 -0
  13. slopaudit-1.0.0/benchmarks/corpus/safe/safe_env_key.py +5 -0
  14. slopaudit-1.0.0/benchmarks/corpus/safe/safe_json_output.py +8 -0
  15. slopaudit-1.0.0/benchmarks/corpus/safe/safe_literal_eval.py +7 -0
  16. slopaudit-1.0.0/benchmarks/corpus/safe/safe_logged_except.py +12 -0
  17. slopaudit-1.0.0/benchmarks/corpus/safe/safe_parameterised_sql.py +5 -0
  18. slopaudit-1.0.0/benchmarks/corpus/safe/safe_real_imports.py +9 -0
  19. slopaudit-1.0.0/benchmarks/corpus/safe/safe_token_cap.py +5 -0
  20. slopaudit-1.0.0/benchmarks/corpus/safe/safe_user_message.py +9 -0
  21. slopaudit-1.0.0/benchmarks/corpus/vulnerable/gap_cross_function.py +8 -0
  22. slopaudit-1.0.0/benchmarks/corpus/vulnerable/gap_instance_attribute.py +12 -0
  23. slopaudit-1.0.0/benchmarks/corpus/vulnerable/hal03_typo.py +6 -0
  24. slopaudit-1.0.0/benchmarks/corpus/vulnerable/inc_chat_residue.py +5 -0
  25. slopaudit-1.0.0/benchmarks/corpus/vulnerable/inc_placeholder.py +5 -0
  26. slopaudit-1.0.0/benchmarks/corpus/vulnerable/inc_stub.py +7 -0
  27. slopaudit-1.0.0/benchmarks/corpus/vulnerable/inc_swallow.py +6 -0
  28. slopaudit-1.0.0/benchmarks/corpus/vulnerable/llm01_format.py +9 -0
  29. slopaudit-1.0.0/benchmarks/corpus/vulnerable/llm01_system_dict.py +8 -0
  30. slopaudit-1.0.0/benchmarks/corpus/vulnerable/llm01_system_prompt.py +9 -0
  31. slopaudit-1.0.0/benchmarks/corpus/vulnerable/llm02_eval_openai.py +7 -0
  32. slopaudit-1.0.0/benchmarks/corpus/vulnerable/llm02_exec_langchain.py +4 -0
  33. slopaudit-1.0.0/benchmarks/corpus/vulnerable/llm03_shell.py +8 -0
  34. slopaudit-1.0.0/benchmarks/corpus/vulnerable/llm04_sql.py +5 -0
  35. slopaudit-1.0.0/benchmarks/corpus/vulnerable/llm05_path.py +6 -0
  36. slopaudit-1.0.0/benchmarks/corpus/vulnerable/llm06_url.py +8 -0
  37. slopaudit-1.0.0/benchmarks/corpus/vulnerable/llm08_shell_tool.py +10 -0
  38. slopaudit-1.0.0/benchmarks/corpus/vulnerable/llm08_toolkit.py +6 -0
  39. slopaudit-1.0.0/benchmarks/corpus/vulnerable/llm09_delete_tool.py +11 -0
  40. slopaudit-1.0.0/benchmarks/corpus/vulnerable/llm12_unbounded.py +5 -0
  41. slopaudit-1.0.0/benchmarks/corpus/vulnerable/sec_password.py +6 -0
  42. slopaudit-1.0.0/benchmarks/realworld.py +137 -0
  43. slopaudit-1.0.0/docs/PRD.md +11 -0
  44. slopaudit-1.0.0/docs/README.md +32 -0
  45. slopaudit-1.0.0/docs/benchmarks.md +86 -0
  46. slopaudit-1.0.0/docs/beyond-scanning.md +82 -0
  47. slopaudit-1.0.0/docs/ci-integration.md +123 -0
  48. slopaudit-1.0.0/docs/clean-room.md +29 -0
  49. slopaudit-1.0.0/docs/cli.md +138 -0
  50. slopaudit-1.0.0/docs/configuration.md +137 -0
  51. slopaudit-1.0.0/docs/decisions/0001-javascript-typescript.md +37 -0
  52. slopaudit-1.0.0/docs/decisions/0002-what-1-0-promises.md +30 -0
  53. slopaudit-1.0.0/docs/decisions/0003-renamed-to-slopaudit.md +27 -0
  54. slopaudit-1.0.0/docs/faq.md +97 -0
  55. slopaudit-1.0.0/docs/getting-started.md +133 -0
  56. slopaudit-1.0.0/docs/how-it-works.md +89 -0
  57. slopaudit-1.0.0/docs/privacy-and-safety.md +52 -0
  58. slopaudit-1.0.0/docs/python-api.md +79 -0
  59. slopaudit-1.0.0/docs/real-world-check.md +36 -0
  60. slopaudit-1.0.0/docs/releasing.md +100 -0
  61. slopaudit-1.0.0/docs/rules.md +320 -0
  62. slopaudit-1.0.0/docs/suppressing-findings.md +58 -0
  63. slopaudit-1.0.0/docs/writing-rules.md +115 -0
  64. slopaudit-1.0.0/examples/SPEC.md +12 -0
  65. slopaudit-1.0.0/examples/github-workflow.yml +22 -0
  66. slopaudit-1.0.0/examples/slopguard.toml +16 -0
  67. slopaudit-1.0.0/examples/vulnerable_agent/app.py +34 -0
  68. slopaudit-1.0.0/pyproject.toml +82 -0
  69. slopaudit-1.0.0/src/slopaudit/__init__.py +24 -0
  70. slopaudit-1.0.0/src/slopaudit/__main__.py +4 -0
  71. slopaudit-1.0.0/src/slopaudit/api.py +103 -0
  72. slopaudit-1.0.0/src/slopaudit/bench.py +136 -0
  73. slopaudit-1.0.0/src/slopaudit/cli.py +465 -0
  74. slopaudit-1.0.0/src/slopaudit/config.py +233 -0
  75. slopaudit-1.0.0/src/slopaudit/context.py +170 -0
  76. slopaudit-1.0.0/src/slopaudit/docgen.py +89 -0
  77. slopaudit-1.0.0/src/slopaudit/drift.py +137 -0
  78. slopaudit-1.0.0/src/slopaudit/engine.py +189 -0
  79. slopaudit-1.0.0/src/slopaudit/gentests.py +118 -0
  80. slopaudit-1.0.0/src/slopaudit/llm.py +193 -0
  81. slopaudit-1.0.0/src/slopaudit/manifest.py +119 -0
  82. slopaudit-1.0.0/src/slopaudit/models.py +127 -0
  83. slopaudit-1.0.0/src/slopaudit/py.typed +0 -0
  84. slopaudit-1.0.0/src/slopaudit/registry.py +137 -0
  85. slopaudit-1.0.0/src/slopaudit/regress.py +190 -0
  86. slopaudit-1.0.0/src/slopaudit/repair.py +182 -0
  87. slopaudit-1.0.0/src/slopaudit/reporters.py +153 -0
  88. slopaudit-1.0.0/src/slopaudit/rules/__init__.py +35 -0
  89. slopaudit-1.0.0/src/slopaudit/rules/drift.py +156 -0
  90. slopaudit-1.0.0/src/slopaudit/rules/hallucination.py +314 -0
  91. slopaudit-1.0.0/src/slopaudit/rules/incomplete.py +344 -0
  92. slopaudit-1.0.0/src/slopaudit/rules/llm_agents.py +220 -0
  93. slopaudit-1.0.0/src/slopaudit/rules/llm_flow.py +159 -0
  94. slopaudit-1.0.0/src/slopaudit/rules/secrets.py +134 -0
  95. slopaudit-1.0.0/src/slopaudit/rules/virtual.py +65 -0
  96. slopaudit-1.0.0/src/slopaudit/sandbox.py +170 -0
  97. slopaudit-1.0.0/src/slopaudit/spec.py +352 -0
  98. slopaudit-1.0.0/src/slopaudit/taint.py +530 -0
  99. slopaudit-1.0.0/tests/conftest.py +108 -0
  100. slopaudit-1.0.0/tests/test_api.py +57 -0
  101. slopaudit-1.0.0/tests/test_bench.py +60 -0
  102. slopaudit-1.0.0/tests/test_cli.py +206 -0
  103. slopaudit-1.0.0/tests/test_docs.py +55 -0
  104. slopaudit-1.0.0/tests/test_drift.py +86 -0
  105. slopaudit-1.0.0/tests/test_gentests.py +106 -0
  106. slopaudit-1.0.0/tests/test_hallucination.py +182 -0
  107. slopaudit-1.0.0/tests/test_incomplete.py +92 -0
  108. slopaudit-1.0.0/tests/test_llm.py +85 -0
  109. slopaudit-1.0.0/tests/test_llm_flow.py +112 -0
  110. slopaudit-1.0.0/tests/test_llm_phase2.py +183 -0
  111. slopaudit-1.0.0/tests/test_realworld_regressions.py +190 -0
  112. slopaudit-1.0.0/tests/test_regress.py +91 -0
  113. slopaudit-1.0.0/tests/test_repair.py +162 -0
  114. slopaudit-1.0.0/tests/test_sandbox.py +82 -0
  115. slopaudit-1.0.0/tests/test_secrets.py +47 -0
  116. slopaudit-1.0.0/tests/test_spec.py +140 -0
@@ -0,0 +1,12 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .venv/
4
+ venv/
5
+ dist/
6
+ build/
7
+ *.egg-info/
8
+ .pytest_cache/
9
+ .ruff_cache/
10
+ .coverage
11
+ htmlcov/
12
+ .slopaudit_cache/
@@ -0,0 +1,113 @@
1
+ # Changelog
2
+
3
+ All notable changes are listed here. The format follows [Keep a Changelog](https://keepachangelog.com/),
4
+ and versions follow [Semantic Versioning](https://semver.org/).
5
+
6
+ ## [1.0.0] - 2026-11-04
7
+
8
+ First stable release, and the first on PyPI. **Renamed from `slopguard` to `slopaudit`**, because PyPI
9
+ refused the old name as too similar to existing projects ([decision 0003](docs/decisions/0003-renamed-to-slopaudit.md)).
10
+ The command is `slopaudit`, the config file `slopaudit.toml`, and suppressions are `# slopaudit: ignore[...]`.
11
+
12
+ **What 1.0 promises:** the scanner (`scan`, every rule not marked experimental, the
13
+ output formats, configuration, baselines and suppressions), `regress`, `bench`, the Python API, the GitHub
14
+ Action and the pre-commit hook. Breaking changes to these wait for 2.0.
15
+
16
+ **Experimental, outside that promise:** `scan --spec --llm`, `gen-tests`, `fix` and the Docker sandbox
17
+ backend. They are tested against local stand-ins, not live services, and may change in a minor release.
18
+ Rules marked `experimental` in `slopaudit rules` may also change. See
19
+ [decision 0002](docs/decisions/0002-what-1-0-promises.md).
20
+
21
+ ### Fixed since 1.0.0rc2
22
+
23
+ - HAL-04 now reads uv and PDM dev dependencies, Hatch environments, `setup.cfg` and `Pipfile`, so packages
24
+ declared there are no longer reported as undeclared.
25
+ - A `pyproject.toml` or `setup.cfg` that only holds tool settings (such as `[tool.ruff]` or `[flake8]`) no
26
+ longer counts as a manifest that declares nothing, which made HAL-04 flag every third-party import.
27
+
28
+ ## [1.0.0rc2] - TestPyPI only, as `slopguard`
29
+
30
+ Fixes from running slopaudit on a real project (an agent with fixture packages and a Postgres store).
31
+
32
+ ### Fixed
33
+
34
+ - HAL-01 and HAL-04 no longer report a package's own modules as unknown when they are imported by absolute
35
+ name from inside a fixture or test folder. Every folder or module in the project now counts as local.
36
+ - HAL-04 reads `requirements*.txt` and `pyproject.toml` from the file's folder and every folder above it, so
37
+ subprojects and fixtures can declare their own dependencies.
38
+ - HAL-03 no longer calls `psycopg` (psycopg 3) a typo of `psycopg2`; other legitimate neighbours of popular
39
+ names were added too.
40
+ - SEC-01 reports credentials named like test data (`FAKE_KEY`, `TEST_API_KEY`) as low severity, so they no
41
+ longer fail builds. Normal names stay critical, and "latest" is not mistaken for "test".
42
+
43
+ ## [1.0.0rc1] - TestPyPI only, as `slopguard`
44
+
45
+ First release candidate. Not yet published to PyPI.
46
+
47
+ ### Added
48
+
49
+ - `slopaudit scan` with terminal, JSON, Markdown and SARIF 2.1.0 output; `--diff`, `--staged`,
50
+ baselines, inline suppressions, and `slopaudit.toml` or `[tool.slopaudit]` configuration.
51
+ - Rules: SEC-01; LLM-01 to LLM-06, LLM-08, LLM-09, LLM-12; HAL-01 to HAL-04; INC-01, INC-02,
52
+ INC-04, INC-05, INC-06, INC-08. See [docs/rules.md](docs/rules.md).
53
+ - A taint tracker for model output, untrusted input and agent-tool arguments (within one function).
54
+ - `scan --spec` requirement checking (SPC-02), with an offline heuristic and optional model judging.
55
+ - Opt-in style drift rules DRF-01 to DRF-03.
56
+ - `slopaudit regress` for deleted, skipped or weakened tests and tests that stopped passing (REG-01, REG-02).
57
+ - `slopaudit gen-tests` with a sandbox (Docker, Linux namespaces, or explicit local).
58
+ - `slopaudit fix`, a verify-and-repair loop that is a dry run unless `--apply` is given.
59
+ - LLM clients for Anthropic, OpenAI and Ollama over plain HTTPS.
60
+ - `slopaudit bench`, a labelled corpus, `benchmarks/compare.py` and `benchmarks/realworld.py`.
61
+ - A composite GitHub Action that uploads SARIF, a pre-commit hook, CI and release workflows.
62
+
63
+ ### Changed after the real-world check
64
+
65
+ Scanning 1.5 million lines of well-reviewed packages found many false positives, and the rules
66
+ were tightened ([details](docs/real-world-check.md)):
67
+
68
+ - SEC-01 no longer flags environment-variable names, endpoints, dotted keys, values that repeat
69
+ the variable name, key headers without key material, or documented example keys.
70
+ - SEC-01 now also finds variables named exactly `token`, `secret` or `password` (they were missed).
71
+ - INC-01 only flags imperative placeholders such as "add your code here".
72
+ - INC-02 reports hollow methods and typed `...` stubs as low severity, and skips functions whose
73
+ docstring explains the intent (hook, override, no-op).
74
+ - INC-04 flags only broad or bare `except ... : pass` with no explanatory comment.
75
+ - HAL-01 knows more import-name aliases and recent stdlib modules, and reports optional, lazy and
76
+ `TYPE_CHECKING` imports as medium.
77
+
78
+ ### Added since the first draft of this release
79
+
80
+ - `slopaudit.scan()` and `slopaudit.scan_source()`, a supported Python API with a `py.typed` marker.
81
+ - `[packages] private` to tell the HAL rules about imports from a private index.
82
+ - Generated reference pages (`slopaudit.docgen`) kept in sync by tests, a full documentation set, and
83
+ contributor files: code of conduct, support guide, issue and pull-request templates, Dependabot,
84
+ `Makefile`, `.editorconfig` and a pre-commit config.
85
+ - A release workflow that dry-runs to TestPyPI and publishes to PyPI by trusted publishing.
86
+
87
+ ### Release pipeline
88
+
89
+ - The PyPI description no longer has broken relative links: the build rewrites them to absolute GitHub
90
+ URLs, and `scripts/check_dist.py` fails the build if any remain.
91
+ - The publishing action is pinned to a commit, and repeated TestPyPI dry runs no longer fail on an
92
+ existing version.
93
+
94
+ ### Safety
95
+
96
+ - `slopaudit fix` never sends a file containing a hardcoded credential to a model.
97
+ - The terminal output warns when no supported files were found, so an unsupported language is not mistaken for a clean scan.
98
+
99
+ ### Fixed
100
+
101
+ - The docs now say `python3` where macOS has no `python`, and `make` defaults to `python3`.
102
+
103
+ ### Removed
104
+
105
+ - The `[llm] max_tokens` setting, which was accepted but never used.
106
+
107
+ ### Known limitations
108
+
109
+ - The taint tracker does not follow values across functions or through instance attributes.
110
+ - The LLM clients and the Docker sandbox backend have not been run against live services.
111
+ - The spec checker without a model can show that code exists, not that it behaves correctly.
112
+ - Python only; see [docs/decisions/0001-javascript-typescript.md](docs/decisions/0001-javascript-typescript.md).
113
+ - The benchmark corpus is small and written by the maintainers.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 slopaudit contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,273 @@
1
+ Metadata-Version: 2.5
2
+ Name: slopaudit
3
+ Version: 1.0.0
4
+ Summary: Verify AI-generated code: LLM-app security, hallucinated packages, stubs and spec drift.
5
+ Project-URL: Homepage, https://github.com/patsypppe/slopaudit
6
+ Project-URL: Repository, https://github.com/patsypppe/slopaudit
7
+ Project-URL: Issues, https://github.com/patsypppe/slopaudit/issues
8
+ Project-URL: Changelog, https://github.com/patsypppe/slopaudit/blob/main/CHANGELOG.md
9
+ Author: slopaudit contributors
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: ai-generated-code,llm,sarif,security,static-analysis
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3 :: Only
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Topic :: Security
25
+ Classifier: Topic :: Software Development :: Quality Assurance
26
+ Requires-Python: >=3.10
27
+ Requires-Dist: rich>=13
28
+ Requires-Dist: tomli>=2; python_version < '3.11'
29
+ Requires-Dist: typer>=0.12
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest-cov>=5; extra == 'dev'
32
+ Requires-Dist: pytest>=8; extra == 'dev'
33
+ Requires-Dist: ruff>=0.5; extra == 'dev'
34
+ Description-Content-Type: text/markdown
35
+
36
+ # slopaudit
37
+
38
+ [![PyPI](https://img.shields.io/pypi/v/slopaudit.svg)](https://pypi.org/project/slopaudit/)
39
+ [![Python versions](https://img.shields.io/pypi/pyversions/slopaudit.svg)](https://pypi.org/project/slopaudit/)
40
+ [![CI](https://github.com/patsypppe/slopaudit/actions/workflows/ci.yml/badge.svg)](https://github.com/patsypppe/slopaudit/actions/workflows/ci.yml)
41
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/patsypppe/slopaudit/blob/main/LICENSE)
42
+ [![Good first issues](https://img.shields.io/github/issues/patsypppe/slopaudit/good%20first%20issue.svg?label=good%20first%20issues)](https://github.com/patsypppe/slopaudit/labels/good%20first%20issue)
43
+
44
+ **Check AI-written code before you trust it.** slopaudit is an open-source command-line tool for Python
45
+ that finds the problems AI assistants and LLM-powered apps tend to introduce, and that general scanners
46
+ were not built to look for.
47
+
48
+ - **Is it safe?** Does model output reach `eval`, a shell or a SQL query? Does untrusted input end up
49
+ in a system prompt? Does an agent tool hand the model a shell?
50
+ - **Is it real?** Does that imported package exist, or is it invented (or one typo from a popular one)?
51
+ - **Is it finished?** Stubs, "rest of code here" comments, swallowed errors, truncated files.
52
+ - **Is it what you asked for?** Does the code meet each requirement in your spec, and did the change
53
+ delete or weaken tests to get there?
54
+
55
+ It runs on your machine, never executes the code it scans, needs no account or API key, and has no telemetry.
56
+
57
+ ## Install
58
+
59
+ You need Python 3.10 or newer. Pick one:
60
+
61
+ ```bash
62
+ pipx install slopaudit # recommended: an isolated command-line tool
63
+ uv tool install slopaudit # same idea, if you use uv
64
+ python3 -m pip install slopaudit # inside a virtual environment
65
+ ```
66
+
67
+ Then check it works:
68
+
69
+ ```bash
70
+ slopaudit --version
71
+ ```
72
+
73
+ **Just try it, without installing anything:**
74
+
75
+ ```bash
76
+ pipx run slopaudit scan . # or: uvx slopaudit scan .
77
+ ```
78
+
79
+ <details>
80
+ <summary>Don't have pipx, upgrading, uninstalling, or installing from source</summary>
81
+
82
+ | I want to | Run |
83
+ | --- | --- |
84
+ | Get pipx on macOS | `brew install pipx && pipx ensurepath` |
85
+ | Get pipx elsewhere | `python3 -m pip install --user pipx && python3 -m pipx ensurepath` |
86
+ | Upgrade | `pipx upgrade slopaudit`, or `python3 -m pip install --upgrade slopaudit` |
87
+ | Uninstall | `pipx uninstall slopaudit`, or `python3 -m pip uninstall slopaudit` |
88
+ | Install a specific version | `pipx install slopaudit==1.0.0` |
89
+ | Install the latest unreleased code | `pipx install git+https://github.com/patsypppe/slopaudit` |
90
+ | Hack on it | `git clone https://github.com/patsypppe/slopaudit && cd slopaudit && make install` (or open it in [Codespaces](https://codespaces.new/patsypppe/slopaudit)) |
91
+
92
+ On macOS and most Linux systems the command is `python3`; `python: command not found` only means that.
93
+ On Windows use `py` instead of `python3`.
94
+
95
+ </details>
96
+
97
+ **In CI**, no install step is needed. Use the GitHub Action:
98
+
99
+ ```yaml
100
+ # .github/workflows/slopaudit.yml
101
+ name: slopaudit
102
+ on: [pull_request]
103
+ permissions: { contents: read, security-events: write }
104
+ jobs:
105
+ scan:
106
+ runs-on: ubuntu-latest
107
+ steps:
108
+ - uses: actions/checkout@v4
109
+ - uses: patsypppe/slopaudit@v1.0.0
110
+ ```
111
+
112
+ **Before every commit**, with [pre-commit](https://pre-commit.com):
113
+
114
+ ```yaml
115
+ # .pre-commit-config.yaml
116
+ repos:
117
+ - repo: https://github.com/patsypppe/slopaudit
118
+ rev: v1.0.0
119
+ hooks:
120
+ - id: slopaudit
121
+ ```
122
+
123
+ ## See it work
124
+
125
+ ```console
126
+ $ slopaudit scan examples/vulnerable_agent
127
+ vulnerable_agent/app.py
128
+ 16 HIGH LLM-08 Tool `run_command` passes a model-chosen argument to subprocess.run() (shell)
129
+ ↳ line 14: tool argument `command` is chosen by the model
130
+ ↳ line 16: passed to subprocess.run()
131
+ 21 HIGH LLM-01 Untrusted input reaches the system prompt of client.messages.create()
132
+ ↳ line 20: untrusted input request.args
133
+ ↳ line 20: stored in `topic`
134
+ ↳ line 21: placed in the system prompt of client.messages.create()
135
+ 27 CRITICAL LLM-02 Model output reaches eval() without validation
136
+ ↳ line 21: model output from client.messages.create()
137
+ ↳ line 21: stored in `reply`
138
+ ↳ line 27: passed to eval()
139
+ 30 MEDIUM INC-02 `parse_invoice` has no implementation (pass)
140
+ 34 CRITICAL SEC-01 Hardcoded credential assignment (q9X$…(21 chars))
141
+
142
+ 1 files scanned: 2 critical, 2 high, 1 medium
143
+ ```
144
+
145
+ Every flow finding shows the path the data took, so you can judge it in seconds. Each finding also has a
146
+ `fix:` line and a longer explanation: `slopaudit explain LLM-02`. No model is involved: slopaudit reads the
147
+ code's structure and follows values from where they come from to where they are used
148
+ ([how it works](https://github.com/patsypppe/slopaudit/blob/main/docs/how-it-works.md)).
149
+
150
+ ## Quickstart
151
+
152
+ ```bash
153
+ slopaudit scan . # scan the current folder
154
+ slopaudit scan . --no-network # skip the PyPI package check
155
+ slopaudit scan --staged # only what you are about to commit
156
+ slopaudit scan . --format sarif -o out.sarif # for GitHub code scanning
157
+ slopaudit scan src --spec SPEC.md # check the code against a requirements file
158
+ slopaudit explain LLM-02 # why a rule exists, and how to fix it
159
+ ```
160
+
161
+ **From Python**, for example to check an assistant's answer before saving it:
162
+
163
+ ```python
164
+ import slopaudit
165
+
166
+ blockers = [f for f in slopaudit.scan_source(answer) if f.severity >= slopaudit.Severity.HIGH]
167
+ ```
168
+
169
+ New to it? The [getting-started guide](https://github.com/patsypppe/slopaudit/blob/main/docs/getting-started.md) takes five minutes, and has a
170
+ ten-line test file that shows every kind of finding. Adopting on a big
171
+ codebase? Start with a [baseline](https://github.com/patsypppe/slopaudit/blob/main/docs/suppressing-findings.md#3-a-baseline-for-existing-code) so only new
172
+ problems fail.
173
+
174
+ ## What it checks
175
+
176
+ | Family | Rules | Catches |
177
+ | --- | --- | --- |
178
+ | **LLM-app security** | LLM-01 to LLM-06, LLM-08, LLM-09, LLM-12 | Prompt-injection paths, model output reaching `eval`, shell, SQL, file paths and URLs, over-permissive agent tools, destructive tools with no confirmation, unbounded model calls |
179
+ | **Secrets** | SEC-01 | Hardcoded API keys, tokens and private keys (masked in all output) |
180
+ | **Hallucinated packages** | HAL-01 to HAL-04 | Imports that do not exist on PyPI, brand-new packages, typosquats, undeclared dependencies |
181
+ | **Unfinished code** | INC-01, INC-02, INC-04, INC-05, INC-06, INC-08 | Placeholder comments, stubs, swallowed exceptions, chat text pasted into files, many TODOs, truncated files |
182
+ | **Intent and consistency** | SPC-02, DRF-01 to DRF-03, REG-01, REG-02 | Unmet requirements, style drift from the rest of the repo, deleted or skipped tests |
183
+
184
+ The full list, with severity and fix advice for each rule, is the [rules reference](https://github.com/patsypppe/slopaudit/blob/main/docs/rules.md).
185
+ Beyond scanning, there are optional model-assisted commands: [`gen-tests`](https://github.com/patsypppe/slopaudit/blob/main/docs/beyond-scanning.md#generated-tests)
186
+ and [`fix`](https://github.com/patsypppe/slopaudit/blob/main/docs/beyond-scanning.md#repair-loop) (a dry run unless you pass `--apply`).
187
+
188
+ ## How well does it work?
189
+
190
+ Three checks, each reproducible from this repository. None is a guarantee; the caveats matter.
191
+
192
+ **1. Labelled corpus** (`slopaudit bench`, 34 files). Every rule scores 1.00 precision; recall is 0.91,
193
+ with two labelled misses (a value that crosses a function boundary, or goes through `self`). The corpus is
194
+ small and was used to tune the rules, so treat it as a regression gate.
195
+
196
+ **2. Other scanners on that corpus** ([full report](https://github.com/patsypppe/slopaudit/blob/main/docs/benchmarks.md)): files flagged at medium
197
+ severity or higher, run as external programs.
198
+
199
+ | Tool | LLM-app security (15) | Secrets (1) | Incomplete code (4) | Hallucinated packages (1) | False alarms on 13 safe files |
200
+ | --- | ---: | ---: | ---: | ---: | ---: |
201
+ | slopaudit | 12 | 1 | 3 | 1 | 0 |
202
+ | Bandit | 6 | 0 | 0 | 0 | 1 |
203
+ | Semgrep, public python rules | 8 | 0 | 2 | 0 | 2 |
204
+ | Semgrep, public ai rules | 12 | 0 | 0 | 0 | 6 |
205
+ | vibechck | 0 | 0 | 2 | 0 | 1 |
206
+
207
+ The corpus targets what slopaudit was built for, so it flatters slopaudit. Bandit and Semgrep are broader
208
+ tools not designed for these cases, and Semgrep's `ai` rules are SDK best-practice lints. Semgrep also
209
+ catches the two cross-function cases slopaudit misses, because it flags any dynamic `eval`.
210
+
211
+ **3. Mature packages as a false-positive control** ([report](https://github.com/patsypppe/slopaudit/blob/main/docs/real-world-check.md)): 1.5 million lines
212
+ across twelve well-reviewed packages, including the OpenAI, Anthropic, LangChain and LiteLLM SDKs.
213
+ **0 critical or high findings** after tuning. The first run had 122 critical findings and about 900 medium
214
+ ones; fixing them is in the [changelog](https://github.com/patsypppe/slopaudit/blob/main/CHANGELOG.md). About 25 medium and a few hundred low findings remain.
215
+ This measures noise only: those packages are not AI-generated.
216
+
217
+ ## Honest limits
218
+
219
+ - **A clean scan is not proof of safety.** The flow rules follow values inside one function. They miss a
220
+ value returned from a helper and `eval`-ed elsewhere, and values stored on `self`
221
+ ([how it works](https://github.com/patsypppe/slopaudit/blob/main/docs/how-it-works.md#what-it-cannot-see)).
222
+ - **Without a model, the spec check compares names and words.** It can show code exists, not that it behaves
223
+ correctly. In the demo it reports a requirement as met while the code does the opposite.
224
+ - **Experimental parts.** `scan --spec --llm`, `gen-tests`, `fix` and the Docker sandbox are tested against
225
+ local stand-ins, not live services, so they are outside the 1.0 stability promise
226
+ ([what 1.0 promises](https://github.com/patsypppe/slopaudit/blob/main/docs/decisions/0002-what-1-0-promises.md)).
227
+ - **Python only.** JavaScript and TypeScript files are skipped, and the scan says so when it finds nothing to read.
228
+ - **Linux CI only.** Installing and running on macOS has been checked by hand; Windows is untested
229
+ ([#6](https://github.com/patsypppe/slopaudit/issues/6)).
230
+
231
+ ## Documentation
232
+
233
+ | | |
234
+ | --- | --- |
235
+ | [Getting started](https://github.com/patsypppe/slopaudit/blob/main/docs/getting-started.md) | Install, first scan, reading output |
236
+ | [Configuration](https://github.com/patsypppe/slopaudit/blob/main/docs/configuration.md) | Every `slopaudit.toml` setting |
237
+ | [CI integration](https://github.com/patsypppe/slopaudit/blob/main/docs/ci-integration.md) | GitHub Action, pre-commit, GitLab |
238
+ | [Suppressing findings](https://github.com/patsypppe/slopaudit/blob/main/docs/suppressing-findings.md) | Comments, baselines, ignores |
239
+ | [Beyond scanning](https://github.com/patsypppe/slopaudit/blob/main/docs/beyond-scanning.md) | Spec checks, generated tests, drift, regression, repair |
240
+ | [Python API](https://github.com/patsypppe/slopaudit/blob/main/docs/python-api.md) | Use it from your own code or agent |
241
+ | [Privacy and safety](https://github.com/patsypppe/slopaudit/blob/main/docs/privacy-and-safety.md) | What runs, what is sent, the sandbox |
242
+ | [How it works](https://github.com/patsypppe/slopaudit/blob/main/docs/how-it-works.md) | Pipeline and taint tracking |
243
+ | [FAQ and troubleshooting](https://github.com/patsypppe/slopaudit/blob/main/docs/faq.md) | Common questions and fixes |
244
+ | [All docs](https://github.com/patsypppe/slopaudit/blob/main/docs/README.md) | The full index |
245
+
246
+ ## Contributing
247
+
248
+ Contributions are welcome: rules, false-positive reports, docs and tests. The most valuable thing you can
249
+ do is **report a false positive or a miss with the smallest code that shows it**; every confirmed report
250
+ becomes a regression test.
251
+
252
+ **Looking for something to work on?** The [contributor roadmap](https://github.com/patsypppe/slopaudit/issues/85)
253
+ lists every open issue by area and difficulty. Each one says why it matters, which files to change, and when
254
+ it is done:
255
+
256
+ | Start here | |
257
+ | --- | --- |
258
+ | [Good first issues](https://github.com/patsypppe/slopaudit/labels/good%20first%20issue) | Small and well-defined: aliases, output formats, docs, test samples |
259
+ | [Help wanted](https://github.com/patsypppe/slopaudit/labels/help%20wanted) | New rules and integrations |
260
+ | [Advanced](https://github.com/patsypppe/slopaudit/labels/advanced) | The flow tracker and bigger design questions; discuss before coding |
261
+
262
+ Comment on an issue before you start so nobody duplicates work. Setup takes one click in
263
+ [Codespaces](https://codespaces.new/patsypppe/slopaudit), or `make install` locally. Start with [CONTRIBUTING.md](https://github.com/patsypppe/slopaudit/blob/main/CONTRIBUTING.md) and
264
+ [writing a rule](https://github.com/patsypppe/slopaudit/blob/main/docs/writing-rules.md), and please follow the [code of conduct](https://github.com/patsypppe/slopaudit/blob/main/CODE_OF_CONDUCT.md).
265
+ Questions go in [Discussions or issues](https://github.com/patsypppe/slopaudit/blob/main/SUPPORT.md); security problems in
266
+ [SECURITY.md](https://github.com/patsypppe/slopaudit/blob/main/SECURITY.md).
267
+
268
+ ## License
269
+
270
+ [MIT](https://github.com/patsypppe/slopaudit/blob/main/LICENSE). slopaudit is independent work: it takes no code, rules, messages or structure from other
271
+ tools. The [clean-room record](https://github.com/patsypppe/slopaudit/blob/main/docs/clean-room.md) explains how, and why other scanners are only ever *run*,
272
+ never copied. Thanks to the authors of Bandit, Semgrep and vibechck for the prior art that made the
273
+ comparison possible.
@@ -0,0 +1,238 @@
1
+ # slopaudit
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/slopaudit.svg)](https://pypi.org/project/slopaudit/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/slopaudit.svg)](https://pypi.org/project/slopaudit/)
5
+ [![CI](https://github.com/patsypppe/slopaudit/actions/workflows/ci.yml/badge.svg)](https://github.com/patsypppe/slopaudit/actions/workflows/ci.yml)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7
+ [![Good first issues](https://img.shields.io/github/issues/patsypppe/slopaudit/good%20first%20issue.svg?label=good%20first%20issues)](https://github.com/patsypppe/slopaudit/labels/good%20first%20issue)
8
+
9
+ **Check AI-written code before you trust it.** slopaudit is an open-source command-line tool for Python
10
+ that finds the problems AI assistants and LLM-powered apps tend to introduce, and that general scanners
11
+ were not built to look for.
12
+
13
+ - **Is it safe?** Does model output reach `eval`, a shell or a SQL query? Does untrusted input end up
14
+ in a system prompt? Does an agent tool hand the model a shell?
15
+ - **Is it real?** Does that imported package exist, or is it invented (or one typo from a popular one)?
16
+ - **Is it finished?** Stubs, "rest of code here" comments, swallowed errors, truncated files.
17
+ - **Is it what you asked for?** Does the code meet each requirement in your spec, and did the change
18
+ delete or weaken tests to get there?
19
+
20
+ It runs on your machine, never executes the code it scans, needs no account or API key, and has no telemetry.
21
+
22
+ ## Install
23
+
24
+ You need Python 3.10 or newer. Pick one:
25
+
26
+ ```bash
27
+ pipx install slopaudit # recommended: an isolated command-line tool
28
+ uv tool install slopaudit # same idea, if you use uv
29
+ python3 -m pip install slopaudit # inside a virtual environment
30
+ ```
31
+
32
+ Then check it works:
33
+
34
+ ```bash
35
+ slopaudit --version
36
+ ```
37
+
38
+ **Just try it, without installing anything:**
39
+
40
+ ```bash
41
+ pipx run slopaudit scan . # or: uvx slopaudit scan .
42
+ ```
43
+
44
+ <details>
45
+ <summary>Don't have pipx, upgrading, uninstalling, or installing from source</summary>
46
+
47
+ | I want to | Run |
48
+ | --- | --- |
49
+ | Get pipx on macOS | `brew install pipx && pipx ensurepath` |
50
+ | Get pipx elsewhere | `python3 -m pip install --user pipx && python3 -m pipx ensurepath` |
51
+ | Upgrade | `pipx upgrade slopaudit`, or `python3 -m pip install --upgrade slopaudit` |
52
+ | Uninstall | `pipx uninstall slopaudit`, or `python3 -m pip uninstall slopaudit` |
53
+ | Install a specific version | `pipx install slopaudit==1.0.0` |
54
+ | Install the latest unreleased code | `pipx install git+https://github.com/patsypppe/slopaudit` |
55
+ | Hack on it | `git clone https://github.com/patsypppe/slopaudit && cd slopaudit && make install` (or open it in [Codespaces](https://codespaces.new/patsypppe/slopaudit)) |
56
+
57
+ On macOS and most Linux systems the command is `python3`; `python: command not found` only means that.
58
+ On Windows use `py` instead of `python3`.
59
+
60
+ </details>
61
+
62
+ **In CI**, no install step is needed. Use the GitHub Action:
63
+
64
+ ```yaml
65
+ # .github/workflows/slopaudit.yml
66
+ name: slopaudit
67
+ on: [pull_request]
68
+ permissions: { contents: read, security-events: write }
69
+ jobs:
70
+ scan:
71
+ runs-on: ubuntu-latest
72
+ steps:
73
+ - uses: actions/checkout@v4
74
+ - uses: patsypppe/slopaudit@v1.0.0
75
+ ```
76
+
77
+ **Before every commit**, with [pre-commit](https://pre-commit.com):
78
+
79
+ ```yaml
80
+ # .pre-commit-config.yaml
81
+ repos:
82
+ - repo: https://github.com/patsypppe/slopaudit
83
+ rev: v1.0.0
84
+ hooks:
85
+ - id: slopaudit
86
+ ```
87
+
88
+ ## See it work
89
+
90
+ ```console
91
+ $ slopaudit scan examples/vulnerable_agent
92
+ vulnerable_agent/app.py
93
+ 16 HIGH LLM-08 Tool `run_command` passes a model-chosen argument to subprocess.run() (shell)
94
+ ↳ line 14: tool argument `command` is chosen by the model
95
+ ↳ line 16: passed to subprocess.run()
96
+ 21 HIGH LLM-01 Untrusted input reaches the system prompt of client.messages.create()
97
+ ↳ line 20: untrusted input request.args
98
+ ↳ line 20: stored in `topic`
99
+ ↳ line 21: placed in the system prompt of client.messages.create()
100
+ 27 CRITICAL LLM-02 Model output reaches eval() without validation
101
+ ↳ line 21: model output from client.messages.create()
102
+ ↳ line 21: stored in `reply`
103
+ ↳ line 27: passed to eval()
104
+ 30 MEDIUM INC-02 `parse_invoice` has no implementation (pass)
105
+ 34 CRITICAL SEC-01 Hardcoded credential assignment (q9X$…(21 chars))
106
+
107
+ 1 files scanned: 2 critical, 2 high, 1 medium
108
+ ```
109
+
110
+ Every flow finding shows the path the data took, so you can judge it in seconds. Each finding also has a
111
+ `fix:` line and a longer explanation: `slopaudit explain LLM-02`. No model is involved: slopaudit reads the
112
+ code's structure and follows values from where they come from to where they are used
113
+ ([how it works](docs/how-it-works.md)).
114
+
115
+ ## Quickstart
116
+
117
+ ```bash
118
+ slopaudit scan . # scan the current folder
119
+ slopaudit scan . --no-network # skip the PyPI package check
120
+ slopaudit scan --staged # only what you are about to commit
121
+ slopaudit scan . --format sarif -o out.sarif # for GitHub code scanning
122
+ slopaudit scan src --spec SPEC.md # check the code against a requirements file
123
+ slopaudit explain LLM-02 # why a rule exists, and how to fix it
124
+ ```
125
+
126
+ **From Python**, for example to check an assistant's answer before saving it:
127
+
128
+ ```python
129
+ import slopaudit
130
+
131
+ blockers = [f for f in slopaudit.scan_source(answer) if f.severity >= slopaudit.Severity.HIGH]
132
+ ```
133
+
134
+ New to it? The [getting-started guide](docs/getting-started.md) takes five minutes, and has a
135
+ ten-line test file that shows every kind of finding. Adopting on a big
136
+ codebase? Start with a [baseline](docs/suppressing-findings.md#3-a-baseline-for-existing-code) so only new
137
+ problems fail.
138
+
139
+ ## What it checks
140
+
141
+ | Family | Rules | Catches |
142
+ | --- | --- | --- |
143
+ | **LLM-app security** | LLM-01 to LLM-06, LLM-08, LLM-09, LLM-12 | Prompt-injection paths, model output reaching `eval`, shell, SQL, file paths and URLs, over-permissive agent tools, destructive tools with no confirmation, unbounded model calls |
144
+ | **Secrets** | SEC-01 | Hardcoded API keys, tokens and private keys (masked in all output) |
145
+ | **Hallucinated packages** | HAL-01 to HAL-04 | Imports that do not exist on PyPI, brand-new packages, typosquats, undeclared dependencies |
146
+ | **Unfinished code** | INC-01, INC-02, INC-04, INC-05, INC-06, INC-08 | Placeholder comments, stubs, swallowed exceptions, chat text pasted into files, many TODOs, truncated files |
147
+ | **Intent and consistency** | SPC-02, DRF-01 to DRF-03, REG-01, REG-02 | Unmet requirements, style drift from the rest of the repo, deleted or skipped tests |
148
+
149
+ The full list, with severity and fix advice for each rule, is the [rules reference](docs/rules.md).
150
+ Beyond scanning, there are optional model-assisted commands: [`gen-tests`](docs/beyond-scanning.md#generated-tests)
151
+ and [`fix`](docs/beyond-scanning.md#repair-loop) (a dry run unless you pass `--apply`).
152
+
153
+ ## How well does it work?
154
+
155
+ Three checks, each reproducible from this repository. None is a guarantee; the caveats matter.
156
+
157
+ **1. Labelled corpus** (`slopaudit bench`, 34 files). Every rule scores 1.00 precision; recall is 0.91,
158
+ with two labelled misses (a value that crosses a function boundary, or goes through `self`). The corpus is
159
+ small and was used to tune the rules, so treat it as a regression gate.
160
+
161
+ **2. Other scanners on that corpus** ([full report](docs/benchmarks.md)): files flagged at medium
162
+ severity or higher, run as external programs.
163
+
164
+ | Tool | LLM-app security (15) | Secrets (1) | Incomplete code (4) | Hallucinated packages (1) | False alarms on 13 safe files |
165
+ | --- | ---: | ---: | ---: | ---: | ---: |
166
+ | slopaudit | 12 | 1 | 3 | 1 | 0 |
167
+ | Bandit | 6 | 0 | 0 | 0 | 1 |
168
+ | Semgrep, public python rules | 8 | 0 | 2 | 0 | 2 |
169
+ | Semgrep, public ai rules | 12 | 0 | 0 | 0 | 6 |
170
+ | vibechck | 0 | 0 | 2 | 0 | 1 |
171
+
172
+ The corpus targets what slopaudit was built for, so it flatters slopaudit. Bandit and Semgrep are broader
173
+ tools not designed for these cases, and Semgrep's `ai` rules are SDK best-practice lints. Semgrep also
174
+ catches the two cross-function cases slopaudit misses, because it flags any dynamic `eval`.
175
+
176
+ **3. Mature packages as a false-positive control** ([report](docs/real-world-check.md)): 1.5 million lines
177
+ across twelve well-reviewed packages, including the OpenAI, Anthropic, LangChain and LiteLLM SDKs.
178
+ **0 critical or high findings** after tuning. The first run had 122 critical findings and about 900 medium
179
+ ones; fixing them is in the [changelog](CHANGELOG.md). About 25 medium and a few hundred low findings remain.
180
+ This measures noise only: those packages are not AI-generated.
181
+
182
+ ## Honest limits
183
+
184
+ - **A clean scan is not proof of safety.** The flow rules follow values inside one function. They miss a
185
+ value returned from a helper and `eval`-ed elsewhere, and values stored on `self`
186
+ ([how it works](docs/how-it-works.md#what-it-cannot-see)).
187
+ - **Without a model, the spec check compares names and words.** It can show code exists, not that it behaves
188
+ correctly. In the demo it reports a requirement as met while the code does the opposite.
189
+ - **Experimental parts.** `scan --spec --llm`, `gen-tests`, `fix` and the Docker sandbox are tested against
190
+ local stand-ins, not live services, so they are outside the 1.0 stability promise
191
+ ([what 1.0 promises](docs/decisions/0002-what-1-0-promises.md)).
192
+ - **Python only.** JavaScript and TypeScript files are skipped, and the scan says so when it finds nothing to read.
193
+ - **Linux CI only.** Installing and running on macOS has been checked by hand; Windows is untested
194
+ ([#6](https://github.com/patsypppe/slopaudit/issues/6)).
195
+
196
+ ## Documentation
197
+
198
+ | | |
199
+ | --- | --- |
200
+ | [Getting started](docs/getting-started.md) | Install, first scan, reading output |
201
+ | [Configuration](docs/configuration.md) | Every `slopaudit.toml` setting |
202
+ | [CI integration](docs/ci-integration.md) | GitHub Action, pre-commit, GitLab |
203
+ | [Suppressing findings](docs/suppressing-findings.md) | Comments, baselines, ignores |
204
+ | [Beyond scanning](docs/beyond-scanning.md) | Spec checks, generated tests, drift, regression, repair |
205
+ | [Python API](docs/python-api.md) | Use it from your own code or agent |
206
+ | [Privacy and safety](docs/privacy-and-safety.md) | What runs, what is sent, the sandbox |
207
+ | [How it works](docs/how-it-works.md) | Pipeline and taint tracking |
208
+ | [FAQ and troubleshooting](docs/faq.md) | Common questions and fixes |
209
+ | [All docs](docs/README.md) | The full index |
210
+
211
+ ## Contributing
212
+
213
+ Contributions are welcome: rules, false-positive reports, docs and tests. The most valuable thing you can
214
+ do is **report a false positive or a miss with the smallest code that shows it**; every confirmed report
215
+ becomes a regression test.
216
+
217
+ **Looking for something to work on?** The [contributor roadmap](https://github.com/patsypppe/slopaudit/issues/85)
218
+ lists every open issue by area and difficulty. Each one says why it matters, which files to change, and when
219
+ it is done:
220
+
221
+ | Start here | |
222
+ | --- | --- |
223
+ | [Good first issues](https://github.com/patsypppe/slopaudit/labels/good%20first%20issue) | Small and well-defined: aliases, output formats, docs, test samples |
224
+ | [Help wanted](https://github.com/patsypppe/slopaudit/labels/help%20wanted) | New rules and integrations |
225
+ | [Advanced](https://github.com/patsypppe/slopaudit/labels/advanced) | The flow tracker and bigger design questions; discuss before coding |
226
+
227
+ Comment on an issue before you start so nobody duplicates work. Setup takes one click in
228
+ [Codespaces](https://codespaces.new/patsypppe/slopaudit), or `make install` locally. Start with [CONTRIBUTING.md](CONTRIBUTING.md) and
229
+ [writing a rule](docs/writing-rules.md), and please follow the [code of conduct](CODE_OF_CONDUCT.md).
230
+ Questions go in [Discussions or issues](SUPPORT.md); security problems in
231
+ [SECURITY.md](SECURITY.md).
232
+
233
+ ## License
234
+
235
+ [MIT](LICENSE). slopaudit is independent work: it takes no code, rules, messages or structure from other
236
+ tools. The [clean-room record](docs/clean-room.md) explains how, and why other scanners are only ever *run*,
237
+ never copied. Thanks to the authors of Bandit, Semgrep and vibechck for the prior art that made the
238
+ comparison possible.