Lei.CommitSubstance (LowEndInsight v0.13.1)

Copy Markdown View Source

Decides whether a commit carries information about a project's maintenance (#244).

Commit currency measures time since the last commit of any kind, which makes it resettable by things that say nothing about whether anyone is paying attention: a README typo, a license year bump, a merged Dependabot PR. A repository with no human involvement for a year can report low on the strength of automation alone -- and because that is true at any threshold, tightening the levels would not reach it.

The same distinction already exists on the contributor axis. contributor_count counts everyone who ever pushed; functional_contributors counts those carrying a real share of the work. Contributors got their filter. This is the one currency never had.

A commit is not substantive when either holds:

  • its author classifies as a bot, which Lei.AgenticDetector already recognises -- Dependabot, Renovate, github-actions, release-please
  • every path it touches is documentation or repository metadata

Note that AI co-authorship does not make a commit non-substantive. An agent-assisted commit still represents a person deciding the project needed changing; agentic_classification is the metric that speaks to that, and conflating the two would answer a different question than this one asks.

Summary

Functions

Whether a repository path is documentation or metadata rather than the work.

Parses git log --name-only output written with the record format this module expects, newest commit first.

A single commit, as %{author_name:, author_email:, files:}.

Functions

documentation?(path)

@spec documentation?(String.t()) :: boolean()

Whether a repository path is documentation or metadata rather than the work.

parse_log(output)

@spec parse_log(String.t()) :: [map()]

Parses git log --name-only output written with the record format this module expects, newest commit first.

Records are separated by \x1e and header fields by \x1f, because both are bytes git will not emit inside a path, an address or a date. Splitting on a printable delimiter would break on the first filename containing it.

warning: lines are dropped for the same reason GitModule.git_log_split/2 drops them: git writes them onto the same stream as the output.

substantive?(arg1)

@spec substantive?(map()) :: boolean()

A single commit, as %{author_name:, author_email:, files:}.

An empty files list is deliberately non-substantive: a commit that changed no path -- an empty commit, or a merge recorded with no diff of its own -- tells us nothing about whether the code is being maintained. Enum.all?/2 would return true for it either way, so this is stated rather than left to fall out of a vacuous truth.