cd /news/developer-tools/ratchets-a-rust-tool-that-polices-st… Β· home β€Ί topics β€Ί developer-tools β€Ί article
[ARTICLE Β· art-28787] src=github.com β†— pub= topic=developer-tools verified=true sentiment=↑ positive

Ratchets: a Rust tool that polices style violations with a flexible budget

Imbue AI released Ratchets, a Rust-based progressive lint enforcement tool that allows codebases to contain existing violations while preventing new ones through a budgeted, ratcheting mechanism. The tool supports region-based budgets, regex and AST rules, and agent-friendly JSONL output, aiming to monotonically decrease technical debt.

read4 min views1 publishedJun 16, 2026

Ratchets is a progressive lint enforcement tool that allows codebases to contain existing violations while preventing new ones. Unlike traditional linters that enforce binary pass/fail, Ratchets permits a budgeted number of violations per rule per region. These budgets can only decrease over time (the "ratchet" mechanism), ensuring technical debt monotonically decreases.

Progressive enforcement: Allow existing violations while preventing new ones** Region-based budgets**: Set different limits for different parts of your codebase** Regex and AST rules**: Match patterns via text or tree-sitter queries** Agent-friendly**: JSONL output, deterministic results, clear exit codes** Fast**: Parallel execution, lazy parser , Rust performance

Install from source using the installation script:

curl -sSf https://raw.githubusercontent.com/imbue-ai/ratchets/main/install.sh | sh

This will automatically build and install ratchets to ~/.cargo/bin/

. Requires Rust/Cargo to be installed.

Initialize Ratchets in your repository:

ratchets init

This creates:

ratchets.toml

β€” Configuration fileratchet-counts.toml

β€” Violation budgetsratchets/

β€” Directory for custom rules

Optionally, drop a .ratchetignore

file at any depth in the tree to exclude paths from ratchet enforcement. Syntax matches .gitignore

(per-directory, nested files compose, negation supported with !

); these files are checked in alongside source.

Run checks:

ratchets check

Verify that violations are within budget:

ratchets check                    # Check all files
ratchets check --format jsonl     # Machine-readable output
ratchets check src/               # Check specific path
ratchets check --since main       # Only files changed since the `main` ref

--since <REF>

shells out to git diff <REF> --name-only

and intersects the result with the file walker's output. Include/exclude/gitignore filters still apply, and files deleted relative to <REF>

are skipped silently. The command exits with code 2 if <REF>

is unknown or the current directory is not inside a git repository.

Increase the violation budget (requires justification in commit message):

ratchets bump no-unwrap --region src/legacy --count 20
ratchets bump no-unwrap --region src/legacy  # Auto-detect current count

Reduce budgets to match current violation counts:

ratchets tighten                    # Tighten all rules
ratchets tighten no-unwrap          # Tighten specific rule
ratchets tighten --region src/      # Tighten specific region

List all enabled rules and their status:

ratchets list
ratchets list --format jsonl

Ratchets uses an explicit opt-in model: rules only fire when listed in enabled_ratchets

(directly or via a $set-name

reference). Anything in disabled_ratchets

is subtracted from the resolved enabled set β€” disabled always wins.

enabled_ratchets = ["$common-starter", "no-unwrap"]
disabled_ratchets = ["no-fixme-comments"]

[ratchets]
version = "2"
languages = ["rust", "typescript"]
include = ["src/**", "tests/**"]
exclude = ["**/generated/**"]

[rules]
no-todo-comments = { severity = "warning" }

[output]
format = "human"

"rule-id"

β€” enables (or disables) a single rule by ID."$set-name"

β€” references aratchet-set: a curated bundle of rule IDs. Sets can compose other sets via$other-set

inside their ownrules

array; cycle-aware resolution catches accidental loops.- The @

sigil is unchanged β€” it still refers to entries in the existing[patterns]

table for glob references.

This binary ships a single starter set:

β€” the language-agnostic curated default. Today's members:$common-starter

no-todo-comments

,no-fixme-comments

. Membership criterion ("stable, broadly applicable, no framework-specific opinions") is documented at the top ofbuiltin-ratchets/sets/common-starter.toml

.

Per-language starter sets ($python-starter

, $rust-starter

, $typescript-starter

) will land in follow-up MRs β€” their curation is its own review topic.

Drop your own set files under ratchets/sets/*.toml

. User-defined sets override embedded sets with the same ID, mirroring how ratchets/regex/

and ratchets/ast/

override embedded rules. A set file looks like:

[set]
id = "house-style"
description = "Rules that match our coding conventions"
rules = ["$common-starter", "no-unwrap"]

enabled_ratchets = ["$house-style"]

then enables the union.

[no-unwrap]
"." = 0
"src/legacy" = 15
"tests" = 50

[no-todo-comments]
"src" = 23

Regions are explicitly configured directory paths. Files in unconfigured subdirectories count toward their nearest configured parent region. Regions are scoped per-rule.

Counts for rules no longer in the resolved enabled set are kept dormant (no cleanup). ratchets tighten

emits a stderr warning naming each orphan so you can re-enable the rule later without losing the count.

Ratchets provides a merge driver that resolves conflicts by taking the minimum count:

ratchet-counts.toml merge=ratchets

[merge "ratchets"]
    name = Ratchets counts merge driver (minimum wins)
    driver = ratchets merge-driver %O %A %B
bash
#!/bin/sh
ratchets check || exit 1
Code Meaning
0 All rules within budget
1 At least one rule exceeded budget
2 Configuration or usage error
3 Parse error in source file

DESIGN.mdβ€” Design specification and rationaleARCHITECTURE.mdβ€” Implementation architecture

The ratchet concept was originally described by qntm: https://qntm.org/ratchet

── more in #developer-tools 4 stories Β· sorted by recency
── more on @ratchets 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/ratchets-a-rust-tool…] indexed:0 read:4min 2026-06-16 Β· β€”