entrolint

module
v0.6.0 Latest Latest
Warning

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

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

README ¶

entrolint

CI Go Reference Go version GitHub Marketplace

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. entrolint scan --html out/ renders the same data as a self-contained HTML treemap (tile area = S, colour = T) — see docs/heatmap.md.

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

# A self-contained HTML heat map of the whole repo (writes out/index.html):
entrolint scan --html out/

# 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.)

scan --html <dir> is separate from --format: it writes a self-contained HTML heat map to <dir>/index.html (a squarified treemap with a per-microstate drill-down, no external assets), rendering the whole repo rather than the table.

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

šŸ“¦ Available on the GitHub Marketplace.

# .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.6.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 Action runs on the Node 24 runtime, so it needs an Actions runner ≄ v2.327.1. GitHub-hosted runners are fine; self-hosted runners must be reasonably current.

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
Cross-file duplication identical AST subtrees copy-pasted across files v0.5

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.6 (latest release) — visualization: an HTML heat map you can show the team. entrolint scan --html out/ writes a self-contained squarified treemap of the repo (tile area = entropy S, colour = temperature T), grouped by package, with file labels and a click-through per-microstate breakdown. The same release hardens the v0.5 engine — a Ī”S-symmetry fix and a markedly cheaper check cross-file pre-pass. Builds on the v0.5 cross_duplication microstate (structurally-identical code copy-pasted across files), the v0.4 CI integration (the drop-in entrolint-check GitHub Action — Ī”S / scaling class / hotspots as a PR comment + SARIF to Code Scanning, plus --format markdown|sarif), 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.

Contributing

Contributions are welcome — see CONTRIBUTING.md. This project follows a Code of Conduct, and security reports go through SECURITY.md.

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/corpus
Package corpus builds the whole-tree cross-file context that backs the cross_duplication microstate.
Package corpus builds the whole-tree cross-file context that backs the cross_duplication microstate.
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