Skip to main content

Personal and opinionated Python linter rules aimed at coding agents.

Project description

garuff

Personal, opinionated Python linter rules aimed at coding agents.

garuff enforces a curated set of conventions that ruff and ty can't express — and it explains every one of them in terms a coding assistant can act on.

⚠️ Early days. The core linter runs — garuff check and garuff rule work today — but the ruleset is still small and there's no packaged release yet. This README describes the vision; the full rule reference and install instructions will land as the implementation does.

Why

Coding agents write a lot of code, fast. Keeping that code consistent means enforcing conventions — but enforcement alone isn't enough for an agent. A terse remove this tells a human who already knows the house style exactly what to do; an agent needs to know why the convention exists, or it will "fix" the symptom and reintroduce the cause a moment later.

ruff and ty are indispensable, and garuff is not a replacement for either. It fills the gap they leave:

  • Conventions they can't express. Repo-specific taste — "return Self, never a stringized forward reference to the enclosing class", "every function carries a docstring", "keep agent-facing docs like ADRs consistently numbered."
  • Messages written for agents. Every rule ships a rationale (why the convention exists) and a prescribed fix (the correct form), not just a one-line complaint.

What makes it different

  • Agent-first by design. Each violation carries a terse summary to locate it, a rationale to justify it, and a fix to resolve it. Output stays scannable: the reasoning for each triggered rule is shown once, not repeated on every hit.
  • Opinionated, not configurable-to-taste. garuff is a point of view, not a style engine. The rules encode one set of preferences; you don't tune them into something else — you take them or turn them off.
  • Enforcement you control. Every rule is on by default. You can ignore individual rules, silence them per file, or suppress a single line inline — while the ruleset itself stays fixed.
  • Zero dependencies. garuff is a tool you install into every project's dev and CI environment, so it leans on nothing but the standard library and drops in without dependency friction.

Using it

garuff check [paths] lints (no paths → the whole project root). Each violation is a terse locator line; once all findings are listed, an appendix explains each rule that fired — once, no matter how many times it tripped:

$ garuff check src
src/config.py:1:1: GAC001 no `from __future__ import annotations`
src/build.py:9:1: GAC008 `build` takes 3 positional parameters (at most 1)

  GAC001  no `from __future__ import annotations`
      why  Python 3.14 evaluates annotations lazily (PEP 649), so the import is
           dead weight — it buys nothing and every module has to carry it.
      fix  Delete the import:
               - from __future__ import annotations

  GAC008  keep positional parameters to at most 1
      why  Positional parameters past the first make a call site ambiguous — the
           reader has to count arguments and match them against the signature to
           know what each one means.
      fix  The limit is 1; move every parameter past it behind
           a bare `*` so callers must name them:
               def build(name, kind, size): ...     # before
               def build(name, *, kind, size): ...  # after
           ...

Findings go to stdout, one per line at column 0; the appendix is indented beneath them, so garuff check | grep '^[^ ]' filters the findings alone.

garuff rule <CODE> prints that same explanation on demand — reading the project's configuration, so a tuned option (say a raised max-positional-args) shows up in the text — and garuff rule --all prints the whole ruleset. A rule you've turned off still explains itself, and says that it's ignored.

Two kinds of rules

  • Code rules — how you write Python and its prose: types, docstrings, naming, model and dataclass conventions.
  • Agent-file rules — how a repository's agent-facing scaffolding is structured: ADRs today, more of the agent surface over time.

Status & direction

The domain model, the key architectural decisions, and the build plan are written down:

Implementation is tracked as a sequence of end-to-end issues. This page will grow into proper documentation as those land.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

garuff-2026.7.0.tar.gz (32.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

garuff-2026.7.0-py3-none-any.whl (46.5 kB view details)

Uploaded Python 3

File details

Details for the file garuff-2026.7.0.tar.gz.

File metadata

  • Download URL: garuff-2026.7.0.tar.gz
  • Upload date:
  • Size: 32.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for garuff-2026.7.0.tar.gz
Algorithm Hash digest
SHA256 9e7639ee24a834c9ff131bc393239e126350891c2b6503cf77d988abec9104f7
MD5 88d49e7c4b01d4c12405bf540c86b706
BLAKE2b-256 23c11ed64967c3d3b81bb6671afd5ec4f7b13a457723a6df0d3159acd4c1b793

See more details on using hashes here.

Provenance

The following attestation bundles were made for garuff-2026.7.0.tar.gz:

Publisher: release.yml on gahjelle/garuff

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file garuff-2026.7.0-py3-none-any.whl.

File metadata

  • Download URL: garuff-2026.7.0-py3-none-any.whl
  • Upload date:
  • Size: 46.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for garuff-2026.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 188efb978875b2f6df1b55341d8ecf10138409daa4d73435e4592f2e3380de17
MD5 0c8b8d5e33fba977bf06123013ce6fc8
BLAKE2b-256 c4927d7b702f0c5a50d08c7ed2b773c8396e3f55f060d25ba8adc8a62a21fa4b

See more details on using hashes here.

Provenance

The following attestation bundles were made for garuff-2026.7.0-py3-none-any.whl:

Publisher: release.yml on gahjelle/garuff

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page