Skip to content

contributors

spanical contributors aggregates the whole window per developer: who landed the volume, and roughly who moved complexity. Where churn --by dev slices by period, this command sums across all of it.

bash
spanical contributors [flags]

Options

OptionValuesNotes
All global flagsSee global flags; --by has no effect here

Behavior

Two tables print, each followed by the metric legend (flags: (signal) safe to read per-dev · (context) needs interpretation · (volume) narrative only, not a ranking):

  1. Whole-window activity per dev, sorted by throughput descending: Author, Commits, Lines added/deleted/net (volume), Throughput churn and Rework lines (context), Files touched (context), Avg commit size and Active days (signal)
  2. Complexity attribution per dev: complexity added/removed/net, complexity per added line, hotspot share

Rework lines charge deleted lines to the original author within reworkWindowDays (default 21 days), whoever held the delete key. Some iteration is healthy; sustained rework is the thrash signal, which is why it is marked context rather than a ranking column.

Fixed notes always follow the tables:

  • Complexity attribution is approximate. scc measures per-file snapshots, not diffs, so only a file's net monthly complexity change is known; one dev's additions and another's removals inside the same file-month cannot be separated
  • How rework is counted: the deletion window in days, charging to the original author, single blame-author credit (Co-authored-by trailers are not split, unlike churn attribution), and no attribution for deletions inside a rename-with-edit commit
  • When rework capture failed for part of a repository, a note says those rework lines are undercounts, not verified zeros
  • When net complexity could not be attributed to anyone, a note gives the unattributed point count

Examples

shell
$ spanical contributors
┌──────────────────┬──────────────────┬ ... ┬──────────────────────┐
│ Author           │ Commits (volume) │ ... │ Active days (signal) │
├──────────────────┼──────────────────┼ ... ┼──────────────────────┤
│ dev2@example.com │               19 │ ... │                   19 │
│ dev1@example.com │               20 │ ... │                   20 │
│ dev3@example.com │                4 │ ... │                    4 │
└──────────────────┴──────────────────┴ ... ┴──────────────────────┘
flags: (signal) safe to read per-dev · (context) needs interpretation · (volume) narrative only, not a ranking

┌──────────────────┬────────────────────────────┬ ... ┬─────────────────────────┐
│ Author           │ Complexity added (context) │ ... │ Hotspot share (context) │
...
└──────────────────┴────────────────────────────┴ ... ┴─────────────────────────┘

Note: complexity attribution is approximate — scc measures per-file snapshots, ...
Note: rework counts lines deleted within 21 days of the commit that wrote them, ...

JSON output; top-level shape with the first contributor row shown in full:

json
{
    "contributors": [
        {
            "period": "last 12m (2025-08 → 2026-08)",
            "authorId": 1,
            "author": "dev3@example.com",
            "commits": 5,
            "added": 17,
            "deleted": 13,
            "net": 4,
            "throughput": 30,
            "filesTouched": 3,
            "avgCommitSize": 6,
            "activeDays": 5,
            "reworkLines": 3
        }
    ],
    "complexity": ["..."],
    "unattributedComplexity": 0,
    "reworkWindowDays": 21,
    "incompleteReworkRepos": []
}

Authors whose emails are not in config.authors appear as raw email addresses (provisional authors), with a warning on stderr listing them:

shell
warning: 3 author email(s) not in config: dev3@example.com, dev2@example.com, dev1@example.com

Map them in the identity bridge to merge their numbers under one canonical author.