beats

module
v0.1.6 Latest Latest
Warning

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

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

README ΒΆ

CI Go Report Card GitHub release Sample Reports


beats

beats

Measure the structural fingerprint of a Go codebase.

beats clusters Go functions by the skeleton of how they are written β€” independent of names, comments, domain vocabulary or semantic meaning. The goal is to find meaningful patterns in code by looking at what it does structurally, not what it means semantically.

πŸ“– Read the full story on Medium β†’

Why beats

Every codebase has a rhythm β€” recurring structural patterns that developers fall into without naming them. Beats finds that pulse. When the rhythm is steady, you have convention. When it's irregular, you have cognitive load.

Well the original idea was to evaluate congnitive load of a piece of code. I generally believe, cognitive load in a codebase isn't caused by complexity alone, it's caused by unexplained structural variance. When every function that does X looks different, your brain can't build a model. Beats finds where the variance is and where it isn't.

Reports from sample OSS repositories
Project Repository Report
Argo CD argoproj/argo-cd View β†’
cAdvisor google/cadvisor View β†’
CockroachDB cockroachdb/cockroach View β†’
Gitea go-gitea/gitea View β†’
Mattermost mattermost/mattermost-server View β†’

What is beats?

beats identifies recurring structural patterns across an entire Go codebase to answer one question: does the golang code across the repository coalesce to form a structural pattern and if so, how can we identify and evaluate the same?

Beats define Structural fingerprint as follows.

For each function, beats computes three features:

  1. Token sequence β€” an ordered list of AST mnemonics representing the structural skeleton of the function body. Each token is a normalised AST node, for example : CALL for a function call, ASSIGN for a variable assignment, RETURN for a return statement (with arity), IF, FOR, RANGE, and so on. No names, no literals β€” only structure.

  2. Direct imports β€” the set of packages actually used within the function (not just imported by the file). This captures the dependency shape at the function level, not the file level.

  3. Call targets (fan-out) β€” the set of external functions invoked within the function body.

No attempt is made to understand what a call target does or what an import statement provides. That would reintroduce vocabulary dependence and defeat the purpose.

These three features β€” along with some additional metadata β€” form a FunctionMetadata record.
Beats collects FunctionMetadata across the entire codebase and clusters structurally similar functions. Similarity between two functions is computed as the geometric mean of three signals, each normalized to [0, 1]: token-sequence similarity (1 βˆ’ normalized Levenshtein distance), Jaccard overlap of imports, and Jaccard overlap of called functions. Using the geometric mean (βˆ›(AΒ·BΒ·C)) rather than a weighted sum means a pair must score well across all three dimensions to be considered similar β€” a function with high token overlap but no shared imports or calls won't be treated as a match

The output is N clusters, each with a coherence value β€” a measure of how tightly packed the function metadata within it are. Coherence is broken into two axes:

High Call Cohesion Low Call Cohesion
High Import Cohesion Tight domain-local pattern β€” shares both package context and call vocabulary. Most actionable. Domain-cohesive, structurally diverse β€” shared package domain, divergent calls. May benefit from splitting.
Low Import Cohesion Cross-cutting structural pattern β€” different domains, same structural role (e.g. cron registration, adapters). Likely noise β€” coincidental structural similarity rather than convention. Treat with scepticism.

πŸ“¦ Installation
Prerequisites
  • Go 1.21 or later
  • Git
Install via Homebrew (macOS / Linux)
brew tap somak2kai/tap
brew install beats

Upgrade to the latest release at any time:

brew upgrade beats
Install from source

Clone the repository and build the CLI:

git clone https://github.com/somak2kai/beats.git
cd beats
go build -o beats ./cmd/

Move the binary somewhere on your $PATH:

mv beats /usr/local/bin/

Or run directly without installing:

go run ./cmd/ <command> [flags]
Verify
beats --version

πŸš€ Usage

beats has one main commands: init to index a repository , to create clusters and report on it.


beats init β€” index a repository

Walks a Go codebase and writes FunctionMetadata records into a local Badger store.

beats init --repo=<path-to-go-repository>

Example:

beats init --repo=/home/user/projects/myservice

What gets indexed:

  • All Go source files under the repository root (excluding vendor/ and test files by default, auto generated files such as pb.go)
  • For each exported and unexported function: token sequence, call targets, direct imports, file path, line number, package name
  • runs the clustering algorithm, and produces an HTML report at <repo>/.beats/report.html.

Open the report:

open /home/user/projects/myservice/.beats/report.html

The report shows all clusters sorted by combined coherence, with per-cluster member lists, top imports, Cyclo P95, package distribution, and a coherence quadrant breakdown.



πŸ“Š Report Analyser

The analyzer/ package contains a Python script for parsing and summarising beats HTML reports in the terminal.

β†’ analyzer/README.md

What it covers:

  • How to run analyze_report.py against any beats report
  • Coherence quadrant reference table
  • Sample output from a real analysis run (Gitea, ~500 clusters)

πŸ”¬ SCIP Validation Tool

The x/tools/cmp/ package contains a comparison tool that validates beats clusters against SCIP (Sourcegraph Code Intelligence Protocol) reference data. It computes precision, recall, and F1 per cluster to measure how well the structural fingerprint aligns with semantic reference graphs.

β†’ x/tools/cmp/README.md

What it covers:

  • Installing and running scip-go on a repository
  • Running the beats vs SCIP comparison
  • How to interpret recall, precision, and F1 in the beats context
  • Why low precision is expected (and desirable) behaviour

Directories ΒΆ

Path Synopsis
pkg
ast
db
x
tools/cmp command
cmp compares beats structural clusters against a SCIP reference-graph index.
cmp compares beats structural clusters against a SCIP reference-graph index.

Jump to

Keyboard shortcuts

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