The repository or configuration that created this release differ from a previous release. View details.
spendlint
Static checks for the code patterns that quietly inflate LLM bills in agent code: missing prompt caching, system prompts that change on every call, unbounded agent loops and retries, cost accounting that ignores cached tokens, and prompt bloat. Python and TypeScript/JavaScript. Pure Python, standard library only.
On a pull request it reports only the lines the pull request adds, as inline annotations, with a summary table and optional SARIF for code scanning. Your code never leaves the runner.
Status: 0.1.0, early. Tested locally by replaying the Action's steps against a real public repository. Not yet verified on GitHub-hosted runners.
Quick start: GitHub Action
name: spendlint
on: pull_request
permissions:
contents: read
jobs:
spendlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: vernialabs/spendlint@v0
Every input (rules, confidence threshold, fail-on, diff mode, SARIF upload, telemetry) is described in
docs/ACTION.md. A complete example is in
examples/.github/workflows/spendlint.yml.
Quick start: CLI
pip install spendlint
spendlint . # scan a checkout
spendlint . --diff pr.patch --fail-on warning # only lines a diff adds; exit 1 on warnings
spendlint . --format sarif --out spendlint.sarif
Exit codes, the .spendlint.yml config file and inline # spendlint: ignore R-XXX-000 reason comments are in
docs/USAGE.md.
What it checks
| Rule | What it flags | Severity | Real-world fixes behind it |
|---|---|---|---|
R-ACCT-001 |
Cost computed from token counts that ignore cached-token fields | warning | 38 |
R-CACHE-001 |
Anthropic requests with no prompt caching anywhere in the repo | warning | 11 |
R-CACHE-003 |
Volatile value (timestamp, uuid, cwd) inside the system prompt | warning | 13 |
R-LOOP-001 |
Agent loop around an LLM call with no iteration/step bound | warning | 3 |
R-LOOP-002 |
Retry on an LLM call with no stop condition | warning | 2 |
R-CTX-008 |
Indented JSON serialized into a prompt | info | 3 |
R-CALL-004 |
Embedding requested one item at a time inside a loop | info | 5 |
R-MEDIA-001 |
Image detail hard-coded to high | info | 0 |
R-OUT-001 |
Chat completion with no output token cap | info | 4 |
R-MODEL-001 |
Frontier model hard-coded for a cheap sub-task | info | 1 |
The last column counts reviewed fixes in open-source agent projects that the rule is based on.
Limits, stated plainly
These are pattern rules, so they see code shape, not dollars or runtime behaviour. In our evaluation the rules caught about 1 in 5 of the real defects their categories cover, and about 7 in 10 findings on repositories they were never tuned on were real patterns. Many costly bugs (cumulative streaming usage, a cap sent under a parameter name the provider ignores) need runtime data and are out of reach for static checks. Treat findings as review prompts, not verdicts.
Telemetry
spendlint records coarse usage counts (version, runtime, file counts by language, finding counts per rule) to a
local file you can read with spendlint telemetry show. It never records code, file names, paths or repository
names. It is off in CI unless you turn it on, and nothing is sent anywhere unless SPENDLINT_TELEMETRY_URL is set.
Turn it off with spendlint telemetry off, SPENDLINT_TELEMETRY=off or DO_NOT_TRACK=1. Full schema:
docs/telemetry.md.
License
spendlint is source-available, not open source. It is licensed under the PolyForm Small Business License 1.0.0: free for individuals, and for companies with fewer than 100 people and under US$1 million in annual revenue (2019 dollars; the license has the exact terms). Larger organisations need a commercial license; see COMMERCIAL.md.
Contributing
See CONTRIBUTING.md. Run the tests with:
python -m spendlint.test_rules && python -m spendlint.test_cli && python -m spendlint.test_telemetry
Metadata
Release files for spendlint 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Change of provenance
The repository or configuration that created these release files differ from that of a previous release.
We recommend inspecting the repository and configuration before proceeding. View details.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| spendlint-0.1.1.tar.gz | 43.0 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| spendlint-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 91.2 kB
Release files / spendlint-0.1.1.tar.gz
Change of provenance
This file belongs to a release with changed provenance: the repository or configuration that created the release files differ from that of a previous release.
We recommend inspecting the repository and configuration before proceeding. View details.
| Download URL | spendlint-0.1.1.tar.gz |
|---|---|
| Size | 43.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
47e9250f3ee83234eada7f263694474eafeb1f6312931c20ebbe16978aaf6ad3
|
|
BLAKE2b-256 checksum How to use checksums |
499c512198b693c62a50e3591f7aef86d9d5c77edd35a72e01e96f722f4e5ccf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logRelease files / spendlint-0.1.1-py3-none-any.whl
Change of provenance
This file belongs to a release with changed provenance: the repository or configuration that created the release files differ from that of a previous release.
We recommend inspecting the repository and configuration before proceeding. View details.
| Download URL | spendlint-0.1.1-py3-none-any.whl |
|---|---|
| Size | 48.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8ab76e7209875cb98c63399264c8be7aaedeea317b278ce97becc3a156928f6a
|
|
BLAKE2b-256 checksum How to use checksums |
ee5bb703f18c542a20f2d85adadb06003da264217d125ce18260a43e4dbe9389
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logSecurity for spendlint 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Change of provenance
The repository that created this release differs from a previous release.
While this could reflect a routine change by the project maintainers, it may also indicate that the release files have been compromised.
Repository
- Removed 0.1.0 GitHub: ishan121028/spendlint
- Added 0.1.1 GitHub: Vernialabs/spendlint
Attestation for spendlint-0.1.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.