Skip to main content

spendlint

Catch the code that inflates your LLM bill, before it ships.

spendlint reads your agent code and points at the patterns that quietly multiply token spend: prompts that never hit the cache, system prompts that change on every call, agent loops with no limit, retries that never stop, and cost reports that miss cached tokens. It works on Python and TypeScript/JavaScript, installs in seconds, and has no dependencies.

On a pull request it only speaks up about the lines that pull request adds, right where you review them. Your code never leaves your machine or your CI runner.

Built by Vernia. Free while we are in early access.

Get started

In GitHub Actions

Add .github/workflows/spendlint.yml:

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

Findings show up as annotations on the changed lines, with a summary on the run page. Every option (rule selection, confidence threshold, failing the build, SARIF for code scanning) is in docs/ACTION.md, and there is a complete example workflow.

On your machine

pip install spendlint
spendlint .                                    # scan a project
spendlint . --diff pr.patch --fail-on warning  # only lines a diff adds; exit 1 on warnings
spendlint . --format sarif --out spendlint.sarif

Configuration, exit codes and inline ignores are in docs/USAGE.md.

What it catches

Rule What it flags Severity
R-ACCT-001 Cost computed from token counts that ignore cached-token fields warning
R-CACHE-001 Anthropic requests with no prompt caching anywhere in the repo warning
R-CACHE-003 A timestamp, uuid or path inside the system prompt, which breaks the cache warning
R-LOOP-001 Agent loop around an LLM call with no step limit warning
R-LOOP-002 Retry on an LLM call with no stop condition warning
R-CTX-008 Pretty-printed JSON sent in a prompt info
R-CALL-004 Embeddings requested one item at a time inside a loop info
R-MEDIA-001 Image detail hard-coded to high info
R-OUT-001 Chat completion with no output token cap info
R-MODEL-001 Frontier model hard-coded for a cheap sub-task info

Every rule comes from a real cost bug that an open-source agent team found and fixed. spendlint reads code, not invoices, so treat each finding as a pointer worth a second look in review.

What's next

spendlint is the first product from Vernia. Next up are Vernia Reason, a reasoning harness that reviews pull requests with the context of the whole repository, and Vernia Ledger, an agent that connects to your providers and billing to tie every dollar to a feature and a customer. Want early access? Write to ishan.upadhyay.iitb@gmail.com.

Telemetry

spendlint keeps anonymous usage counts so we can see which rules help and where they get in the way. Here is exactly what that means:

  • What is recorded: spendlint version, Python version, operating system, CI provider, how many files were scanned per language, how many findings each rule produced, run time, exit code, the hour of the run, and a random install id.
  • What is never recorded: your code, file names, paths, repository names, or anything that identifies you.
  • Where it goes: a local file you can read at any time with spendlint telemetry show. Counts are sent only when a collection endpoint is configured through SPENDLINT_TELEMETRY_URL.
  • In CI: off by default. Turn it on with SPENDLINT_TELEMETRY=on or the Action's telemetry: on input.
  • Turning it off: spendlint telemetry off, SPENDLINT_TELEMETRY=off, or DO_NOT_TRACK=1.

The full schema is in docs/telemetry.md. A paid plan with telemetry fully disabled is on the way for teams that need it.

License

spendlint is source-available under the PolyForm Small Business License 1.0.0. It is free for individuals and for companies with fewer than 100 people and under US$1 million in annual revenue (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.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for spendlint 0.1.2
File Size Uploaded Provenance
spendlint-0.1.2.tar.gz 43.6 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for spendlint 0.1.2
File Interpreter ABI Platform
spendlint-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 92.0 kB

Release files / spendlint-0.1.2.tar.gz

Download URL spendlint-0.1.2.tar.gz
Size 43.6 kB
Tags Source
SHA-256 checksum
How to use checksums
cff63b511362e8427c90daccbe165f770640ae1985548e6a04bbd7f762e85040
BLAKE2b-256 checksum
How to use checksums
39aa79f38035e4fe6a0eb59c439cd3f38ced611d8a9725d38330bbdb96984a57
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 log

Release files / spendlint-0.1.2-py3-none-any.whl

Download URL spendlint-0.1.2-py3-none-any.whl
Size 48.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e94300a57a2a3c3a94af34f6de79c83b524f44071cf79fe15772bdb7b402a070
BLAKE2b-256 checksum
How to use checksums
4f82037991e3942d2387d15b15becb94bb45f80935a4e516fe9bdea6977fa3b5
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 log

Security for spendlint 0.1.2

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for spendlint-0.1.2.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 log

A 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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page