entrolint

module
v0.4.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 7, 2026 License: MIT

README

entrolint

CI Go Reference Go version

Code rots toward disorder. entrolint measures the entropy — and keeps it from growing on every PR.

entrolint gauges code quality and maintainability through the metaphor of entropy from statistical physics. Clean, ordered, easy-to-change code is a system with low entropy. Tangled, tightly-coupled, hard-to-maintain code is a system with high entropy.

And just as in the second law of thermodynamics, the entropy of a codebase only grows when left unattended. entrolint's job is to measure it and keep it from growing unnoticed.

🔒 Runs entirely locally — no network calls, no telemetry, ever.

Why

Ordinary linters catch individual style violations. entrolint looks at the whole picture: it gives you a single number — entropy — that reflects how hard the code will be to maintain, and shows how that number changes with every change.

Two modes

scan — a heat map of the whole repo

Walks the codebase, computes an entropy score (S) for every file and package, and highlights hotspots — the places with the highest entropy. These are the first candidates for refactoring.

check — a pull-request gate

Computes ΔS (the entropy delta) between base and head: did the change raise disorder or lower it. It plugs into CI and blocks PRs that worsen maintainability beyond a configured threshold.

Positive ΔS = the code became harder to maintain.

Installation

go install github.com/pavlov061356/entrolint/cmd/entrolint@latest

Or download a prebuilt binary from the latest release.

Quick start

# The 10 hottest files in the repo:
entrolint scan --top 10

# PR gate: compare a feature branch against dev, fail if the threshold is exceeded.
entrolint check --base dev --head HEAD

# Machine-readable report for CI / a PR bot:
entrolint check --base origin/dev --head HEAD --format json > delta.json

scan prints a table with the columns PATH | S | T | DOMINANT. check prints a verdict line (PASS/FAIL) plus a per-file breakdown and returns exit code 1 when delta_s_max is exceeded.

Output formats

Both commands take --format:

Command Formats Notable use
scan table (default), json, sarif sarif → GitHub Code Scanning
check table (default), json, markdown markdown → a PR-comment body

(--json is a deprecated alias for --format json.)

Configuration

.entrolint.yaml at the repository root (optional — defaults are used when the file is absent):

weights:
  cyclomatic: 1.0
  nesting:    0.8
  coupling:   0.6
  length:     0.5
  duplication: 0.7
delta_s_max:       0.05   # ΔS_density threshold for check
churn_since_days:  90     # window for the churn factor (lives in T, not S)

Using entrolint in CI

entrolint ships a composite GitHub Action that posts a sticky PR comment with ΔS, the scaling class and the hottest changed files, and (optionally) uploads a SARIF log to GitHub Code Scanning. No Go toolchain is needed on the runner — the Action downloads the released binary.

# .github/workflows/entrolint.yml
name: entrolint
on:
  pull_request:
permissions:
  contents: read
  pull-requests: write     # post the PR comment
  security-events: write   # upload SARIF (optional)
jobs:
  entrolint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0
      - run: git fetch --no-tags origin "+refs/heads/${{ github.base_ref }}:refs/remotes/origin/${{ github.base_ref }}"
      - uses: pavlov061356/entrolint@v0
        with:
          comment: true
          upload-sarif: true
          fail-on-gate: false   # set true to block PRs that raise entropy
Input Default Description
version latest latest, a tag (v0.4.0), or source (build from the checkout).
base PR base branch Base ref for ΔS (origin/<base_ref> on PRs).
head HEAD Head ref.
config .entrolint.yaml Path to the config; defaults to .entrolint.yaml at the root.
comment true Post / update the sticky PR comment.
upload-sarif false Upload the scan SARIF to Code Scanning.
fail-on-gate false Fail the job when the ΔS / scaling gate trips.
github-token github.token Token used to post the PR comment and upload SARIF.

Fork PRs get a read-only GITHUB_TOKEN, so the comment step is skipped on PRs from forks (the Action stays on pull_request, not pull_request_target).

The entropy model

Entropy is a weighted sum of "microstates" — individual measurable factors of disorder. In the spirit of Boltzmann's formula S = k · ln(W): the more ways the code can be tangled, the higher the entropy.

Microstates that contribute to S:

Microstate What it measures Since
Cyclomatic complexity how many branches there are in the code v0.1
Nesting depth how deeply blocks are nested v0.1
Function / file length the size of code units v0.1
Coupling how many import specs a file has v0.3
Duplication repeated AST subtrees within a file v0.3

Churn (how often a file changes) feeds the temperature T = S · ξ(churn) — the hottest spots are not merely complex but also frequently rewritten.

Upcoming microstates and milestones are tracked in the ROADMAP.

Terminology

  • Entropy (S) — a measure of disorder and maintenance difficulty. Higher = worse.
  • ΔS — the change in entropy introduced by a pull request.
  • Hotspot — a file or package with high entropy.
  • Microstate — an individual factor contributing to S.
  • Temperature — a file's normalized entropy, used for the heat map.

Status

📦 v0.4 (latest release) — CI integration: a drop-in entrolint-check GitHub Action that comments ΔS / scaling class / hotspots on a PR and uploads SARIF to Code Scanning, plus --format markdown|sarif output. Built on the v0.3 structural microstates (coupling, duplication) and the v0.2 predictive scaling class (O-class detectors shotgun, implementor_scan, switch_case_symmetry, identifier_fanout, state_multiplier emit a scaling_class line next to ΔS). The formula, weights, and threshold are considered unstable until v1.0 — S values may shift between releases.

License

MIT (see LICENSE).

Directories

Path Synopsis
cmd
entrolint command
internal
cli
Package cli wires the entrolint command tree.
Package cli wires the entrolint command tree.
engine/analyzer/golang
Package golang walks a Go module/directory and produces parsed microstate.File values ready for scoring.
Package golang walks a Go module/directory and produces parsed microstate.File values ready for scoring.
engine/cache
Package cache persists thermo calibration parameters to `.entrolint.cache.json` so subsequent scans don't have to refit the lognormal distributions or recompute k.
Package cache persists thermo calibration parameters to `.entrolint.cache.json` so subsequent scans don't have to refit the lognormal distributions or recompute k.
engine/config
Package config loads entrolint's per-repo configuration from `.entrolint.yaml`.
Package config loads entrolint's per-repo configuration from `.entrolint.yaml`.
engine/gitx
Package gitx wraps the local git operations entrolint needs.
Package gitx wraps the local git operations entrolint needs.
engine/microstate
Package microstate defines the contract for entrolint entropy contributors and provides the per-microstate implementations.
Package microstate defines the contract for entrolint entropy contributors and provides the per-microstate implementations.
engine/pipeline
Package pipeline orchestrates the entrolint analysis end-to-end: walks the source tree, computes microstates, calibrates the thermo engine (or loads cached calibration), and produces ranked file scores.
Package pipeline orchestrates the entrolint analysis end-to-end: walks the source tree, computes microstates, calibrates the thermo engine (or loads cached calibration), and produces ranked file scores.
engine/thermo
Package thermo implements the entrolint v0.1 entropy formula: S = k · Σᵢ wᵢ · ln(1 + mᵢ_norm), with per-microstate self- calibrated lognormal-CDF normalization and k chosen so that the median file scores S = 1.
Package thermo implements the entrolint v0.1 entropy formula: S = k · Σᵢ wᵢ · ln(1 + mᵢ_norm), with per-microstate self- calibrated lognormal-CDF normalization and k chosen so that the median file scores S = 1.
report
Package report renders the typed engine results into integration formats — a Markdown PR comment and a SARIF code-scanning log — that the GitHub Action consumes.
Package report renders the typed engine results into integration formats — a Markdown PR comment and a SARIF code-scanning log — that the GitHub Action consumes.
scaling
Package scaling computes the predictive scaling class (O-notation) of a PR alongside the descriptive ΔS.
Package scaling computes the predictive scaling class (O-notation) of a PR alongside the descriptive ΔS.
scaling/detectors/identifierfanout
Package identifierfanout detects PRs that touch ≥ TouchedRatio of the call-sites of an exported symbol the PR also defines — the O(refs) shape from docs/scaling.md.
Package identifierfanout detects PRs that touch ≥ TouchedRatio of the call-sites of an exported symbol the PR also defines — the O(refs) shape from docs/scaling.md.
scaling/detectors/implementorscan
Package implementorscan detects PRs that ripple through ≥ a configurable fraction of an interface's implementors — the canonical O(implementors) shape from docs/scaling.md.
Package implementorscan detects PRs that ripple through ≥ a configurable fraction of an interface's implementors — the canonical O(implementors) shape from docs/scaling.md.
scaling/detectors/shotgun
Package shotgun detects scatter-PR patterns: one logical change scattered across ≥ MinFiles Go files with no common AST parent.
Package shotgun detects scatter-PR patterns: one logical change scattered across ≥ MinFiles Go files with no common AST parent.
scaling/detectors/statemultiplier
Package statemultiplier detects PRs that add a state-multiplying parameter (bool or enum-typed) to an exported function or method — the O(2ⁿ) shape from docs/scaling.md.
Package statemultiplier detects PRs that add a state-multiplying parameter (bool or enum-typed) to an exported function or method — the O(2ⁿ) shape from docs/scaling.md.
scaling/detectors/switchsymmetry
Package switchsymmetry detects PRs that touch ≥ a configurable fraction of `switch` statements over the same enum-like named type — the O(switch arms) shape from docs/scaling.md.
Package switchsymmetry detects PRs that touch ≥ a configurable fraction of `switch` statements over the same enum-like named type — the O(switch arms) shape from docs/scaling.md.
scaling/typesx
Package typesx provides the shared go/types loading and lookup helpers used by every typed scaling detector.
Package typesx provides the shared go/types loading and lookup helpers used by every typed scaling detector.
version
Package version exposes build-time identification.
Package version exposes build-time identification.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL