Skip to main content

ovecc coupling

The file pairs the history keeps changing in the same commit, whether or not anything in the code connects them.

Usage: ovecc coupling [OPTIONS]

Static analysis sees imports. It cannot see that every change to the parser has needed a matching change to the tokenizer for the last thirty commits. That coupling is real, it is expensive, and the only witness is the git history.

Example

$ ovecc coupling --limit 3
Evolutionary coupling:

crates/ovecc-core/src/capabilities.rs <-> crates/ovecc-indexer/src/lib.rs
18 commits together, jaccard 0.41, lift 1.87
64% of changes to the first touch the second, 53% the other way
seen in 755bb485, 2cb16120, cd8022e7, cfdb9dc5, b3f8eaa2

crates/ovecc-cli/src/cli.rs <-> crates/ovecc-cli/src/mcp.rs
18 commits together, jaccard 0.38, lift 1.71
45% of changes to the first touch the second, 69% the other way
seen in 446317b9, b3f8eaa2, e84eb8c3, 889ee38d, 42914eeb

crates/ovecc-core/src/capabilities.rs <-> crates/ovecc-core/src/facts.rs
17 commits together, jaccard 0.46, lift 2.31
61% of changes to the first touch the second, 65% the other way
seen in 755bb485, 2cb16120, cfdb9dc5, b3f8eaa2, 42914eeb

Reading the numbers

FigureMeaning
commits togetherHow many commits touched both files
jaccardShared commits over the union — symmetric strength
liftHow much more often than chance. This is what separates a real pair from two merely busy files
directed confidenceBoth directions, because they are rarely equal. "69% the other way" means the second file is the one that drags the first along
witness shasThe commits themselves, so you can go read them

Asymmetric confidence is the useful part. A pair where one direction is 90% and the other is 20% is not a mutual dependency — it is one file that cannot move without the other.

What counts as a commit

Only commits touching between 2 and 30 indexed files count. One file says nothing about a pair, and a sweep across the whole tree says nothing about any of them.

A pair is stored when it met at least 3 times, with Jaccard at least 0.35 and lift above 1.

Empty without git history.

Options

OptionEffect
--min-confidence <f>Drop pairs where neither file reaches this share of changes to the other (default 0, which keeps every stored pair)
--limit <n>Pairs to print, strongest first (default 20; 0 prints all)

Plus the global options.