@mneme-ai/core 0.8.4 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/entities/go-parser.d.ts +47 -0
- package/dist/entities/go-parser.d.ts.map +1 -0
- package/dist/entities/go-parser.js +315 -0
- package/dist/entities/go-parser.js.map +1 -0
- package/dist/entities/go-parser.test.d.ts +2 -0
- package/dist/entities/go-parser.test.d.ts.map +1 -0
- package/dist/entities/go-parser.test.js +147 -0
- package/dist/entities/go-parser.test.js.map +1 -0
- package/dist/entities/index.d.ts +1 -0
- package/dist/entities/index.d.ts.map +1 -1
- package/dist/entities/index.js +1 -0
- package/dist/entities/index.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/indexer/indexer.d.ts +12 -0
- package/dist/indexer/indexer.d.ts.map +1 -1
- package/dist/indexer/indexer.js +28 -1
- package/dist/indexer/indexer.js.map +1 -1
- package/dist/insights/bus-factor.d.ts +58 -0
- package/dist/insights/bus-factor.d.ts.map +1 -0
- package/dist/insights/bus-factor.js +117 -0
- package/dist/insights/bus-factor.js.map +1 -0
- package/dist/insights/bus-factor.test.d.ts +2 -0
- package/dist/insights/bus-factor.test.d.ts.map +1 -0
- package/dist/insights/bus-factor.test.js +149 -0
- package/dist/insights/bus-factor.test.js.map +1 -0
- package/dist/insights/commit-coach.d.ts +80 -0
- package/dist/insights/commit-coach.d.ts.map +1 -0
- package/dist/insights/commit-coach.js +230 -0
- package/dist/insights/commit-coach.js.map +1 -0
- package/dist/insights/commit-coach.test.d.ts +2 -0
- package/dist/insights/commit-coach.test.d.ts.map +1 -0
- package/dist/insights/commit-coach.test.js +163 -0
- package/dist/insights/commit-coach.test.js.map +1 -0
- package/dist/insights/crystal-ball.d.ts +76 -0
- package/dist/insights/crystal-ball.d.ts.map +1 -0
- package/dist/insights/crystal-ball.js +219 -0
- package/dist/insights/crystal-ball.js.map +1 -0
- package/dist/insights/crystal-ball.test.d.ts +2 -0
- package/dist/insights/crystal-ball.test.d.ts.map +1 -0
- package/dist/insights/crystal-ball.test.js +157 -0
- package/dist/insights/crystal-ball.test.js.map +1 -0
- package/dist/insights/decisions.d.ts +38 -0
- package/dist/insights/decisions.d.ts.map +1 -0
- package/dist/insights/decisions.js +125 -0
- package/dist/insights/decisions.js.map +1 -0
- package/dist/insights/decisions.test.d.ts +2 -0
- package/dist/insights/decisions.test.d.ts.map +1 -0
- package/dist/insights/decisions.test.js +141 -0
- package/dist/insights/decisions.test.js.map +1 -0
- package/dist/insights/dream.d.ts +71 -0
- package/dist/insights/dream.d.ts.map +1 -0
- package/dist/insights/dream.js +235 -0
- package/dist/insights/dream.js.map +1 -0
- package/dist/insights/dream.test.d.ts +2 -0
- package/dist/insights/dream.test.d.ts.map +1 -0
- package/dist/insights/dream.test.js +127 -0
- package/dist/insights/dream.test.js.map +1 -0
- package/dist/insights/index.d.ts +21 -0
- package/dist/insights/index.d.ts.map +1 -0
- package/dist/insights/index.js +21 -0
- package/dist/insights/index.js.map +1 -0
- package/dist/insights/obsidian.d.ts +42 -0
- package/dist/insights/obsidian.d.ts.map +1 -0
- package/dist/insights/obsidian.js +263 -0
- package/dist/insights/obsidian.js.map +1 -0
- package/dist/insights/obsidian.test.d.ts +2 -0
- package/dist/insights/obsidian.test.d.ts.map +1 -0
- package/dist/insights/obsidian.test.js +241 -0
- package/dist/insights/obsidian.test.js.map +1 -0
- package/dist/insights/paradox.d.ts +36 -0
- package/dist/insights/paradox.d.ts.map +1 -0
- package/dist/insights/paradox.js +201 -0
- package/dist/insights/paradox.js.map +1 -0
- package/dist/insights/paradox.test.d.ts +2 -0
- package/dist/insights/paradox.test.d.ts.map +1 -0
- package/dist/insights/paradox.test.js +88 -0
- package/dist/insights/paradox.test.js.map +1 -0
- package/dist/insights/regret.d.ts +57 -0
- package/dist/insights/regret.d.ts.map +1 -0
- package/dist/insights/regret.js +137 -0
- package/dist/insights/regret.js.map +1 -0
- package/dist/insights/regret.test.d.ts +2 -0
- package/dist/insights/regret.test.d.ts.map +1 -0
- package/dist/insights/regret.test.js +153 -0
- package/dist/insights/regret.test.js.map +1 -0
- package/dist/insights/stack-trace.d.ts +40 -0
- package/dist/insights/stack-trace.d.ts.map +1 -0
- package/dist/insights/stack-trace.js +127 -0
- package/dist/insights/stack-trace.js.map +1 -0
- package/dist/insights/stack-trace.test.d.ts +2 -0
- package/dist/insights/stack-trace.test.d.ts.map +1 -0
- package/dist/insights/stack-trace.test.js +103 -0
- package/dist/insights/stack-trace.test.js.map +1 -0
- package/dist/insights/story.d.ts +34 -0
- package/dist/insights/story.d.ts.map +1 -0
- package/dist/insights/story.js +100 -0
- package/dist/insights/story.js.map +1 -0
- package/dist/insights/story.test.d.ts +2 -0
- package/dist/insights/story.test.d.ts.map +1 -0
- package/dist/insights/story.test.js +99 -0
- package/dist/insights/story.test.js.map +1 -0
- package/dist/insights/suggest.d.ts +29 -0
- package/dist/insights/suggest.d.ts.map +1 -0
- package/dist/insights/suggest.js +93 -0
- package/dist/insights/suggest.js.map +1 -0
- package/dist/insights/suggest.test.d.ts +2 -0
- package/dist/insights/suggest.test.d.ts.map +1 -0
- package/dist/insights/suggest.test.js +71 -0
- package/dist/insights/suggest.test.js.map +1 -0
- package/dist/insights/who-knows.d.ts +66 -0
- package/dist/insights/who-knows.d.ts.map +1 -0
- package/dist/insights/who-knows.js +125 -0
- package/dist/insights/who-knows.js.map +1 -0
- package/dist/insights/who-knows.test.d.ts +2 -0
- package/dist/insights/who-knows.test.d.ts.map +1 -0
- package/dist/insights/who-knows.test.js +109 -0
- package/dist/insights/who-knows.test.js.map +1 -0
- package/dist/quant/alpha.d.ts +87 -0
- package/dist/quant/alpha.d.ts.map +1 -0
- package/dist/quant/alpha.js +103 -0
- package/dist/quant/alpha.js.map +1 -0
- package/dist/quant/alpha.test.d.ts +2 -0
- package/dist/quant/alpha.test.d.ts.map +1 -0
- package/dist/quant/alpha.test.js +147 -0
- package/dist/quant/alpha.test.js.map +1 -0
- package/dist/quant/backtest.d.ts +57 -0
- package/dist/quant/backtest.d.ts.map +1 -0
- package/dist/quant/backtest.js +90 -0
- package/dist/quant/backtest.js.map +1 -0
- package/dist/quant/backtest.test.d.ts +2 -0
- package/dist/quant/backtest.test.d.ts.map +1 -0
- package/dist/quant/backtest.test.js +133 -0
- package/dist/quant/backtest.test.js.map +1 -0
- package/dist/quant/black-swan.d.ts +45 -0
- package/dist/quant/black-swan.d.ts.map +1 -0
- package/dist/quant/black-swan.js +112 -0
- package/dist/quant/black-swan.js.map +1 -0
- package/dist/quant/black-swan.test.d.ts +2 -0
- package/dist/quant/black-swan.test.d.ts.map +1 -0
- package/dist/quant/black-swan.test.js +131 -0
- package/dist/quant/black-swan.test.js.map +1 -0
- package/dist/quant/correlation-matrix.d.ts +54 -0
- package/dist/quant/correlation-matrix.d.ts.map +1 -0
- package/dist/quant/correlation-matrix.js +103 -0
- package/dist/quant/correlation-matrix.js.map +1 -0
- package/dist/quant/correlation-matrix.test.d.ts +2 -0
- package/dist/quant/correlation-matrix.test.d.ts.map +1 -0
- package/dist/quant/correlation-matrix.test.js +118 -0
- package/dist/quant/correlation-matrix.test.js.map +1 -0
- package/dist/quant/drawdown.d.ts +51 -0
- package/dist/quant/drawdown.d.ts.map +1 -0
- package/dist/quant/drawdown.js +96 -0
- package/dist/quant/drawdown.js.map +1 -0
- package/dist/quant/drawdown.test.d.ts +2 -0
- package/dist/quant/drawdown.test.d.ts.map +1 -0
- package/dist/quant/drawdown.test.js +166 -0
- package/dist/quant/drawdown.test.js.map +1 -0
- package/dist/quant/greek.d.ts +55 -0
- package/dist/quant/greek.d.ts.map +1 -0
- package/dist/quant/greek.js +157 -0
- package/dist/quant/greek.js.map +1 -0
- package/dist/quant/greek.test.d.ts +2 -0
- package/dist/quant/greek.test.d.ts.map +1 -0
- package/dist/quant/greek.test.js +138 -0
- package/dist/quant/greek.test.js.map +1 -0
- package/dist/quant/implied-volatility.d.ts +65 -0
- package/dist/quant/implied-volatility.d.ts.map +1 -0
- package/dist/quant/implied-volatility.js +149 -0
- package/dist/quant/implied-volatility.js.map +1 -0
- package/dist/quant/implied-volatility.test.d.ts +2 -0
- package/dist/quant/implied-volatility.test.d.ts.map +1 -0
- package/dist/quant/implied-volatility.test.js +127 -0
- package/dist/quant/implied-volatility.test.js.map +1 -0
- package/dist/quant/index.d.ts +28 -0
- package/dist/quant/index.d.ts.map +1 -0
- package/dist/quant/index.js +28 -0
- package/dist/quant/index.js.map +1 -0
- package/dist/quant/insider-trading.d.ts +56 -0
- package/dist/quant/insider-trading.d.ts.map +1 -0
- package/dist/quant/insider-trading.js +129 -0
- package/dist/quant/insider-trading.js.map +1 -0
- package/dist/quant/insider-trading.test.d.ts +2 -0
- package/dist/quant/insider-trading.test.d.ts.map +1 -0
- package/dist/quant/insider-trading.test.js +130 -0
- package/dist/quant/insider-trading.test.js.map +1 -0
- package/dist/quant/moneyball.d.ts +48 -0
- package/dist/quant/moneyball.d.ts.map +1 -0
- package/dist/quant/moneyball.js +110 -0
- package/dist/quant/moneyball.js.map +1 -0
- package/dist/quant/moneyball.test.d.ts +2 -0
- package/dist/quant/moneyball.test.d.ts.map +1 -0
- package/dist/quant/moneyball.test.js +137 -0
- package/dist/quant/moneyball.test.js.map +1 -0
- package/dist/quant/tax-loss-harvest.d.ts +59 -0
- package/dist/quant/tax-loss-harvest.d.ts.map +1 -0
- package/dist/quant/tax-loss-harvest.js +126 -0
- package/dist/quant/tax-loss-harvest.js.map +1 -0
- package/dist/quant/tax-loss-harvest.test.d.ts +2 -0
- package/dist/quant/tax-loss-harvest.test.d.ts.map +1 -0
- package/dist/quant/tax-loss-harvest.test.js +126 -0
- package/dist/quant/tax-loss-harvest.test.js.map +1 -0
- package/dist/retrieve/index.d.ts +2 -0
- package/dist/retrieve/index.d.ts.map +1 -1
- package/dist/retrieve/index.js +2 -0
- package/dist/retrieve/index.js.map +1 -1
- package/dist/retrieve/intent.d.ts +32 -0
- package/dist/retrieve/intent.d.ts.map +1 -0
- package/dist/retrieve/intent.js +104 -0
- package/dist/retrieve/intent.js.map +1 -0
- package/dist/retrieve/intent.test.d.ts +2 -0
- package/dist/retrieve/intent.test.d.ts.map +1 -0
- package/dist/retrieve/intent.test.js +106 -0
- package/dist/retrieve/intent.test.js.map +1 -0
- package/dist/retrieve/search.d.ts +30 -0
- package/dist/retrieve/search.d.ts.map +1 -1
- package/dist/retrieve/search.js +48 -0
- package/dist/retrieve/search.js.map +1 -1
- package/dist/retrieve/search.test.js +84 -1
- package/dist/retrieve/search.test.js.map +1 -1
- package/dist/retrieve/synthesize.d.ts +57 -0
- package/dist/retrieve/synthesize.d.ts.map +1 -0
- package/dist/retrieve/synthesize.js +191 -0
- package/dist/retrieve/synthesize.js.map +1 -0
- package/dist/retrieve/synthesize.test.d.ts +2 -0
- package/dist/retrieve/synthesize.test.d.ts.map +1 -0
- package/dist/retrieve/synthesize.test.js +127 -0
- package/dist/retrieve/synthesize.test.js.map +1 -0
- package/dist/store/schema.d.ts +2 -2
- package/dist/store/schema.d.ts.map +1 -1
- package/dist/store/schema.js +60 -2
- package/dist/store/schema.js.map +1 -1
- package/dist/store/sqlite.d.ts +2 -0
- package/dist/store/sqlite.d.ts.map +1 -1
- package/dist/store/sqlite.js +24 -0
- package/dist/store/sqlite.js.map +1 -1
- package/dist/store/sqlite.test.js +1 -1
- package/dist/util/index.d.ts +2 -0
- package/dist/util/index.d.ts.map +1 -1
- package/dist/util/index.js +2 -1
- package/dist/util/index.js.map +1 -1
- package/dist/util/redact.d.ts +58 -0
- package/dist/util/redact.d.ts.map +1 -0
- package/dist/util/redact.js +129 -0
- package/dist/util/redact.js.map +1 -0
- package/dist/util/redact.test.d.ts +2 -0
- package/dist/util/redact.test.d.ts.map +1 -0
- package/dist/util/redact.test.js +148 -0
- package/dist/util/redact.test.js.map +1 -0
- package/dist/wisdom/calibrator.d.ts +43 -0
- package/dist/wisdom/calibrator.d.ts.map +1 -0
- package/dist/wisdom/calibrator.js +120 -0
- package/dist/wisdom/calibrator.js.map +1 -0
- package/dist/wisdom/feedback.d.ts +45 -0
- package/dist/wisdom/feedback.d.ts.map +1 -0
- package/dist/wisdom/feedback.js +116 -0
- package/dist/wisdom/feedback.js.map +1 -0
- package/dist/wisdom/index.d.ts +15 -0
- package/dist/wisdom/index.d.ts.map +1 -0
- package/dist/wisdom/index.js +15 -0
- package/dist/wisdom/index.js.map +1 -0
- package/dist/wisdom/types.d.ts +67 -0
- package/dist/wisdom/types.d.ts.map +1 -0
- package/dist/wisdom/types.js +20 -0
- package/dist/wisdom/types.js.map +1 -0
- package/dist/wisdom/wisdom.test.d.ts +2 -0
- package/dist/wisdom/wisdom.test.d.ts.map +1 -0
- package/dist/wisdom/wisdom.test.js +144 -0
- package/dist/wisdom/wisdom.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"correlation-matrix.js","sourceRoot":"","sources":["../../src/quant/correlation-matrix.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"correlation-matrix.test.d.ts","sourceRoot":"","sources":["../../src/quant/correlation-matrix.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { correlationMatrix, classifyCouplingTier } from "./correlation-matrix.js";
|
|
3
|
+
const cmt = (hash, date, files) => ({
|
|
4
|
+
hash,
|
|
5
|
+
shortHash: hash.slice(0, 7),
|
|
6
|
+
authorName: "alice",
|
|
7
|
+
authorEmail: "a@x",
|
|
8
|
+
authorDate: `${date}T00:00:00Z`,
|
|
9
|
+
committerDate: `${date}T00:00:00Z`,
|
|
10
|
+
subject: "x",
|
|
11
|
+
body: "",
|
|
12
|
+
parents: [],
|
|
13
|
+
files,
|
|
14
|
+
});
|
|
15
|
+
describe("classifyCouplingTier", () => {
|
|
16
|
+
it("'tight' when both jaccard ≥ 0.6 + lift ≥ 5", () => {
|
|
17
|
+
expect(classifyCouplingTier(0.7, 6)).toBe("tight");
|
|
18
|
+
});
|
|
19
|
+
it("'strong' when one of jaccard ≥ 0.4 or lift ≥ 3", () => {
|
|
20
|
+
expect(classifyCouplingTier(0.5, 1)).toBe("strong");
|
|
21
|
+
expect(classifyCouplingTier(0.1, 4)).toBe("strong");
|
|
22
|
+
});
|
|
23
|
+
it("'moderate' for middling values", () => {
|
|
24
|
+
expect(classifyCouplingTier(0.25, 2)).toBe("moderate");
|
|
25
|
+
});
|
|
26
|
+
it("'weak' otherwise", () => {
|
|
27
|
+
expect(classifyCouplingTier(0.05, 1.2)).toBe("weak");
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
describe("correlationMatrix — basic detection", () => {
|
|
31
|
+
it("returns empty when there are no co-occurring file pairs", () => {
|
|
32
|
+
const commits = [
|
|
33
|
+
cmt("a1", "2024-01-01", ["src/a.ts"]),
|
|
34
|
+
cmt("a2", "2024-01-02", ["src/b.ts"]),
|
|
35
|
+
cmt("a3", "2024-01-03", ["src/c.ts"]),
|
|
36
|
+
];
|
|
37
|
+
expect(correlationMatrix(commits)).toEqual([]);
|
|
38
|
+
});
|
|
39
|
+
it("detects a tightly-coupled pair when both files always change together", () => {
|
|
40
|
+
// 10 co-touched commits + 20 background commits on unrelated files.
|
|
41
|
+
// Background commits lower the baseline rate of x and y so that
|
|
42
|
+
// co-occurrence has lift > 1.5 (otherwise lift = 1 and is filtered out).
|
|
43
|
+
const co = Array.from({ length: 10 }, (_, i) => cmt(`c${i}`.padEnd(7, "x"), `2024-01-${String(i + 1).padStart(2, "0")}`, ["src/x.ts", "src/y.ts"]));
|
|
44
|
+
const bg = Array.from({ length: 20 }, (_, i) => cmt(`bg${i}`.padEnd(7, "x"), `2024-02-${String((i % 28) + 1).padStart(2, "0")}`, [`src/other${i}.ts`]));
|
|
45
|
+
const pairs = correlationMatrix([...co, ...bg], { minFileTouches: 3, minCoOccurrences: 2 });
|
|
46
|
+
const xy = pairs.find((p) => (p.fileA === "src/x.ts" && p.fileB === "src/y.ts") ||
|
|
47
|
+
(p.fileA === "src/y.ts" && p.fileB === "src/x.ts"));
|
|
48
|
+
expect(xy).toBeDefined();
|
|
49
|
+
expect(xy.jaccard).toBeCloseTo(1, 3);
|
|
50
|
+
expect(xy.tier).toBe("tight");
|
|
51
|
+
});
|
|
52
|
+
it("respects minFileTouches threshold", () => {
|
|
53
|
+
const commits = [
|
|
54
|
+
cmt("a1", "2024-01-01", ["src/x.ts", "src/y.ts"]),
|
|
55
|
+
cmt("a2", "2024-01-02", ["src/x.ts", "src/y.ts"]),
|
|
56
|
+
];
|
|
57
|
+
expect(correlationMatrix(commits, { minFileTouches: 5 })).toEqual([]);
|
|
58
|
+
expect(correlationMatrix(commits, { minFileTouches: 1, minCoOccurrences: 1, minLift: 0 })).toHaveLength(1);
|
|
59
|
+
});
|
|
60
|
+
it("respects minCoOccurrences threshold", () => {
|
|
61
|
+
const commits = [
|
|
62
|
+
cmt("a1", "2024-01-01", ["src/x.ts", "src/y.ts"]),
|
|
63
|
+
cmt("a2", "2024-01-02", ["src/x.ts"]),
|
|
64
|
+
cmt("a3", "2024-01-03", ["src/y.ts"]),
|
|
65
|
+
cmt("a4", "2024-01-04", ["src/x.ts"]),
|
|
66
|
+
];
|
|
67
|
+
expect(correlationMatrix(commits, { minFileTouches: 1, minCoOccurrences: 3 })).toEqual([]);
|
|
68
|
+
});
|
|
69
|
+
it("respects minLift threshold (filters weak pairs)", () => {
|
|
70
|
+
// Build a noisy history where x and y co-occur but at random level
|
|
71
|
+
const commits = [];
|
|
72
|
+
for (let i = 0; i < 20; i++)
|
|
73
|
+
commits.push(cmt(`x${i}`.padEnd(7, "y"), `2024-01-${String(i + 1).padStart(2, "0")}`, ["src/x.ts"]));
|
|
74
|
+
for (let i = 0; i < 20; i++)
|
|
75
|
+
commits.push(cmt(`y${i}`.padEnd(7, "x"), `2024-02-${String(i + 1).padStart(2, "0")}`, ["src/y.ts"]));
|
|
76
|
+
commits.push(cmt("co1", "2024-03-01", ["src/x.ts", "src/y.ts"]));
|
|
77
|
+
commits.push(cmt("co2", "2024-03-02", ["src/x.ts", "src/y.ts"]));
|
|
78
|
+
// 2 co-occurrences but x has 22 total, y has 22 total, so jaccard tiny + lift low
|
|
79
|
+
expect(correlationMatrix(commits, { minLift: 5 })).toEqual([]);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
describe("correlationMatrix — sort + tiers", () => {
|
|
83
|
+
it("sorts by lift desc", () => {
|
|
84
|
+
const commits = [
|
|
85
|
+
// Pair 1: TIGHT (5 co-occurrences, files appear in nothing else).
|
|
86
|
+
cmt("a1", "2024-01-01", ["src/tight-a.ts", "src/tight-b.ts"]),
|
|
87
|
+
cmt("a2", "2024-01-02", ["src/tight-a.ts", "src/tight-b.ts"]),
|
|
88
|
+
cmt("a3", "2024-01-03", ["src/tight-a.ts", "src/tight-b.ts"]),
|
|
89
|
+
cmt("a4", "2024-01-04", ["src/tight-a.ts", "src/tight-b.ts"]),
|
|
90
|
+
cmt("a5", "2024-01-05", ["src/tight-a.ts", "src/tight-b.ts"]),
|
|
91
|
+
// Pair 2: LOOSER (3 co, but both files also touched alone — diluted lift).
|
|
92
|
+
cmt("b1", "2024-02-01", ["src/loose-a.ts", "src/loose-b.ts"]),
|
|
93
|
+
cmt("b2", "2024-02-02", ["src/loose-a.ts", "src/loose-b.ts"]),
|
|
94
|
+
cmt("b3", "2024-02-03", ["src/loose-a.ts", "src/loose-b.ts"]),
|
|
95
|
+
cmt("b4", "2024-02-04", ["src/loose-a.ts"]),
|
|
96
|
+
cmt("b5", "2024-02-05", ["src/loose-a.ts"]),
|
|
97
|
+
cmt("b6", "2024-02-06", ["src/loose-b.ts"]),
|
|
98
|
+
cmt("b7", "2024-02-07", ["src/loose-b.ts"]),
|
|
99
|
+
// Background — 15 commits on unrelated files lower the global baseline,
|
|
100
|
+
// so even the tight pair has lift > 1.5 (otherwise lift = 1 and filtered).
|
|
101
|
+
...Array.from({ length: 15 }, (_, i) => cmt(`bg${i}`.padEnd(7, "x"), `2024-03-${String(i + 1).padStart(2, "0")}`, [`src/other${i}.ts`])),
|
|
102
|
+
];
|
|
103
|
+
const pairs = correlationMatrix(commits, { minFileTouches: 3, minCoOccurrences: 2 });
|
|
104
|
+
expect(pairs[0].fileA).toMatch(/tight-/);
|
|
105
|
+
expect(pairs[0].lift).toBeGreaterThan(pairs[pairs.length - 1].lift);
|
|
106
|
+
});
|
|
107
|
+
it("respects topN", () => {
|
|
108
|
+
const commits = [];
|
|
109
|
+
// 10 file pairs, each with 4 co-occurrences
|
|
110
|
+
for (let p = 0; p < 10; p++) {
|
|
111
|
+
for (let i = 0; i < 4; i++) {
|
|
112
|
+
commits.push(cmt(`p${p}c${i}`.padEnd(7, "x"), `2024-${String(p + 1).padStart(2, "0")}-0${i + 1}`, [`src/p${p}-a.ts`, `src/p${p}-b.ts`]));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
expect(correlationMatrix(commits, { minFileTouches: 1, minCoOccurrences: 2, topN: 5, minLift: 0 }).length).toBeLessThanOrEqual(5);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
//# sourceMappingURL=correlation-matrix.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"correlation-matrix.test.js","sourceRoot":"","sources":["../../src/quant/correlation-matrix.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mneme drawdown` — find the worst "losing streaks" in repo history.
|
|
3
|
+
*
|
|
4
|
+
* In finance, a drawdown is a peak-to-trough decline. In a codebase, it's
|
|
5
|
+
* a stretch of bug-fix-only commits with no feature progress — pure
|
|
6
|
+
* firefighting. Surfacing these is gold for retrospectives:
|
|
7
|
+
*
|
|
8
|
+
* "We spent 3 weeks last September shipping nothing but fixes."
|
|
9
|
+
*
|
|
10
|
+
* Pure data analysis. No LLM. Tested via TDD against synthetic histories.
|
|
11
|
+
*/
|
|
12
|
+
import type { Commit } from "../types.js";
|
|
13
|
+
export interface Drawdown {
|
|
14
|
+
/** Start commit (peak — last feat before the drawdown). */
|
|
15
|
+
startHash: string;
|
|
16
|
+
startDate: string;
|
|
17
|
+
/** End commit (trough — last fix in the streak). */
|
|
18
|
+
endHash: string;
|
|
19
|
+
endDate: string;
|
|
20
|
+
/** Number of consecutive non-feat commits in the streak. */
|
|
21
|
+
length: number;
|
|
22
|
+
/** Days between start and end. */
|
|
23
|
+
durationDays: number;
|
|
24
|
+
/** Sample fix subjects from inside the streak (up to 3). */
|
|
25
|
+
sampleFixes: string[];
|
|
26
|
+
/** Severity tier from length × duration. */
|
|
27
|
+
tier: "minor" | "moderate" | "severe" | "critical";
|
|
28
|
+
}
|
|
29
|
+
/** Decide whether a commit subject is a "fix" (counts toward drawdown). */
|
|
30
|
+
export declare function isFixCommit(c: Commit): boolean;
|
|
31
|
+
/** Decide whether a commit subject is a "feature" (resets the streak). */
|
|
32
|
+
export declare function isFeatCommit(c: Commit): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Detect drawdowns — runs of ≥ minLength consecutive non-feat commits
|
|
35
|
+
* where ≥ fixRatio of those commits are explicit fixes.
|
|
36
|
+
*/
|
|
37
|
+
export declare function detectDrawdowns(commits: Commit[], opts?: {
|
|
38
|
+
minLength?: number;
|
|
39
|
+
fixRatio?: number;
|
|
40
|
+
topN?: number;
|
|
41
|
+
}): Drawdown[];
|
|
42
|
+
export declare function classifyDrawdown(length: number, durationDays: number): Drawdown["tier"];
|
|
43
|
+
export interface DrawdownSummary {
|
|
44
|
+
total: number;
|
|
45
|
+
longestStreak: number;
|
|
46
|
+
totalFixingDays: number;
|
|
47
|
+
/** Fraction of the repo's lifespan spent in drawdown. */
|
|
48
|
+
drawdownFraction: number;
|
|
49
|
+
}
|
|
50
|
+
export declare function summarizeDrawdowns(commits: Commit[], drawdowns: Drawdown[]): DrawdownSummary;
|
|
51
|
+
//# sourceMappingURL=drawdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawdown.d.ts","sourceRoot":"","sources":["../../src/quant/drawdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,WAAW,QAAQ;IACvB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,4CAA4C;IAC5C,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;CACpD;AAKD,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE9C;AAED,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAClE,QAAQ,EAAE,CA4CZ;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAKvF;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,eAAe,CAiB5F"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mneme drawdown` — find the worst "losing streaks" in repo history.
|
|
3
|
+
*
|
|
4
|
+
* In finance, a drawdown is a peak-to-trough decline. In a codebase, it's
|
|
5
|
+
* a stretch of bug-fix-only commits with no feature progress — pure
|
|
6
|
+
* firefighting. Surfacing these is gold for retrospectives:
|
|
7
|
+
*
|
|
8
|
+
* "We spent 3 weeks last September shipping nothing but fixes."
|
|
9
|
+
*
|
|
10
|
+
* Pure data analysis. No LLM. Tested via TDD against synthetic histories.
|
|
11
|
+
*/
|
|
12
|
+
const FEAT_RE = /^feat[(:]/i;
|
|
13
|
+
const FIX_RE = /^(fix|hotfix|bug|revert|patch)[(:]/i;
|
|
14
|
+
/** Decide whether a commit subject is a "fix" (counts toward drawdown). */
|
|
15
|
+
export function isFixCommit(c) {
|
|
16
|
+
return FIX_RE.test(c.subject);
|
|
17
|
+
}
|
|
18
|
+
/** Decide whether a commit subject is a "feature" (resets the streak). */
|
|
19
|
+
export function isFeatCommit(c) {
|
|
20
|
+
return FEAT_RE.test(c.subject);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Detect drawdowns — runs of ≥ minLength consecutive non-feat commits
|
|
24
|
+
* where ≥ fixRatio of those commits are explicit fixes.
|
|
25
|
+
*/
|
|
26
|
+
export function detectDrawdowns(commits, opts = {}) {
|
|
27
|
+
const minLength = opts.minLength ?? 3;
|
|
28
|
+
const fixRatio = opts.fixRatio ?? 0.5;
|
|
29
|
+
const topN = opts.topN ?? 10;
|
|
30
|
+
const sorted = [...commits].sort((a, b) => a.authorDate.localeCompare(b.authorDate));
|
|
31
|
+
const out = [];
|
|
32
|
+
let i = 0;
|
|
33
|
+
while (i < sorted.length) {
|
|
34
|
+
if (isFeatCommit(sorted[i])) {
|
|
35
|
+
i += 1;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
// Walk forward while non-feat.
|
|
39
|
+
let j = i;
|
|
40
|
+
let fixCount = 0;
|
|
41
|
+
while (j < sorted.length && !isFeatCommit(sorted[j])) {
|
|
42
|
+
if (isFixCommit(sorted[j]))
|
|
43
|
+
fixCount += 1;
|
|
44
|
+
j += 1;
|
|
45
|
+
}
|
|
46
|
+
const length = j - i;
|
|
47
|
+
const ratio = length === 0 ? 0 : fixCount / length;
|
|
48
|
+
if (length >= minLength && ratio >= fixRatio) {
|
|
49
|
+
const start = sorted[i];
|
|
50
|
+
const end = sorted[j - 1];
|
|
51
|
+
const dur = (new Date(end.authorDate).getTime() - new Date(start.authorDate).getTime()) / 86_400_000;
|
|
52
|
+
const samples = sorted.slice(i, j).filter(isFixCommit).slice(0, 3).map((c) => c.subject);
|
|
53
|
+
out.push({
|
|
54
|
+
startHash: start.shortHash || start.hash.slice(0, 7),
|
|
55
|
+
startDate: start.authorDate.slice(0, 10),
|
|
56
|
+
endHash: end.shortHash || end.hash.slice(0, 7),
|
|
57
|
+
endDate: end.authorDate.slice(0, 10),
|
|
58
|
+
length,
|
|
59
|
+
durationDays: Math.round(dur * 10) / 10,
|
|
60
|
+
sampleFixes: samples,
|
|
61
|
+
tier: classifyDrawdown(length, dur),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
i = j === i ? i + 1 : j;
|
|
65
|
+
}
|
|
66
|
+
// Sort by severity (length × duration), desc.
|
|
67
|
+
out.sort((a, b) => b.length * Math.max(b.durationDays, 1) - a.length * Math.max(a.durationDays, 1));
|
|
68
|
+
return out.slice(0, topN);
|
|
69
|
+
}
|
|
70
|
+
export function classifyDrawdown(length, durationDays) {
|
|
71
|
+
if (length >= 15 || durationDays >= 30)
|
|
72
|
+
return "critical";
|
|
73
|
+
if (length >= 8 || durationDays >= 14)
|
|
74
|
+
return "severe";
|
|
75
|
+
if (length >= 5 || durationDays >= 7)
|
|
76
|
+
return "moderate";
|
|
77
|
+
return "minor";
|
|
78
|
+
}
|
|
79
|
+
export function summarizeDrawdowns(commits, drawdowns) {
|
|
80
|
+
if (commits.length === 0) {
|
|
81
|
+
return { total: 0, longestStreak: 0, totalFixingDays: 0, drawdownFraction: 0 };
|
|
82
|
+
}
|
|
83
|
+
const sorted = [...commits].sort((a, b) => a.authorDate.localeCompare(b.authorDate));
|
|
84
|
+
const repoSpan = (new Date(sorted[sorted.length - 1].authorDate).getTime() -
|
|
85
|
+
new Date(sorted[0].authorDate).getTime()) /
|
|
86
|
+
86_400_000;
|
|
87
|
+
const totalFixingDays = drawdowns.reduce((s, d) => s + d.durationDays, 0);
|
|
88
|
+
const longest = drawdowns.reduce((m, d) => Math.max(m, d.length), 0);
|
|
89
|
+
return {
|
|
90
|
+
total: drawdowns.length,
|
|
91
|
+
longestStreak: longest,
|
|
92
|
+
totalFixingDays: Math.round(totalFixingDays * 10) / 10,
|
|
93
|
+
drawdownFraction: repoSpan === 0 ? 0 : totalFixingDays / repoSpan,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=drawdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawdown.js","sourceRoot":"","sources":["../../src/quant/drawdown.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawdown.test.d.ts","sourceRoot":"","sources":["../../src/quant/drawdown.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { detectDrawdowns, summarizeDrawdowns, isFeatCommit, isFixCommit, classifyDrawdown, } from "./drawdown.js";
|
|
3
|
+
const cmt = (hash, date, subject) => ({
|
|
4
|
+
hash,
|
|
5
|
+
shortHash: hash.slice(0, 7),
|
|
6
|
+
authorName: "alice",
|
|
7
|
+
authorEmail: "alice@x",
|
|
8
|
+
authorDate: `${date}T00:00:00Z`,
|
|
9
|
+
committerDate: `${date}T00:00:00Z`,
|
|
10
|
+
subject,
|
|
11
|
+
body: "",
|
|
12
|
+
parents: [],
|
|
13
|
+
files: [],
|
|
14
|
+
});
|
|
15
|
+
describe("isFeatCommit / isFixCommit — Conventional-Commit subject classifiers", () => {
|
|
16
|
+
it("matches feat( and feat:", () => {
|
|
17
|
+
expect(isFeatCommit(cmt("a", "2024-01-01", "feat: thing"))).toBe(true);
|
|
18
|
+
expect(isFeatCommit(cmt("a", "2024-01-01", "feat(auth): thing"))).toBe(true);
|
|
19
|
+
expect(isFeatCommit(cmt("a", "2024-01-01", "feat scoped without colon"))).toBe(false);
|
|
20
|
+
});
|
|
21
|
+
it("matches fix/hotfix/bug/revert/patch", () => {
|
|
22
|
+
expect(isFixCommit(cmt("a", "2024-01-01", "fix: x"))).toBe(true);
|
|
23
|
+
expect(isFixCommit(cmt("a", "2024-01-01", "hotfix: x"))).toBe(true);
|
|
24
|
+
expect(isFixCommit(cmt("a", "2024-01-01", "bug: x"))).toBe(true);
|
|
25
|
+
expect(isFixCommit(cmt("a", "2024-01-01", "revert: x"))).toBe(true);
|
|
26
|
+
expect(isFixCommit(cmt("a", "2024-01-01", "feat: x"))).toBe(false);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
describe("classifyDrawdown — tier from length × duration", () => {
|
|
30
|
+
it("critical at 15+ commits or 30+ days", () => {
|
|
31
|
+
expect(classifyDrawdown(15, 5)).toBe("critical");
|
|
32
|
+
expect(classifyDrawdown(5, 30)).toBe("critical");
|
|
33
|
+
});
|
|
34
|
+
it("severe at 8+ or 14+", () => {
|
|
35
|
+
expect(classifyDrawdown(8, 5)).toBe("severe");
|
|
36
|
+
expect(classifyDrawdown(5, 14)).toBe("severe");
|
|
37
|
+
});
|
|
38
|
+
it("moderate at 5+ or 7+", () => {
|
|
39
|
+
expect(classifyDrawdown(5, 1)).toBe("moderate");
|
|
40
|
+
expect(classifyDrawdown(3, 7)).toBe("moderate");
|
|
41
|
+
});
|
|
42
|
+
it("minor for short streaks", () => {
|
|
43
|
+
expect(classifyDrawdown(3, 2)).toBe("minor");
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
describe("detectDrawdowns — simple cases", () => {
|
|
47
|
+
it("returns empty when no fix commits", () => {
|
|
48
|
+
const commits = [
|
|
49
|
+
cmt("a1", "2024-01-01", "feat: A"),
|
|
50
|
+
cmt("a2", "2024-01-02", "feat: B"),
|
|
51
|
+
cmt("a3", "2024-01-03", "feat: C"),
|
|
52
|
+
];
|
|
53
|
+
expect(detectDrawdowns(commits)).toEqual([]);
|
|
54
|
+
});
|
|
55
|
+
it("returns empty when streak shorter than minLength", () => {
|
|
56
|
+
const commits = [
|
|
57
|
+
cmt("a1", "2024-01-01", "feat: A"),
|
|
58
|
+
cmt("a2", "2024-01-02", "fix: x"),
|
|
59
|
+
cmt("a3", "2024-01-03", "fix: y"),
|
|
60
|
+
cmt("a4", "2024-01-04", "feat: B"),
|
|
61
|
+
];
|
|
62
|
+
expect(detectDrawdowns(commits, { minLength: 3 })).toEqual([]);
|
|
63
|
+
});
|
|
64
|
+
it("detects a single drawdown of 5 fixes between two feats", () => {
|
|
65
|
+
const commits = [
|
|
66
|
+
cmt("a1", "2024-01-01", "feat: A"),
|
|
67
|
+
cmt("a2", "2024-01-02", "fix: 1"),
|
|
68
|
+
cmt("a3", "2024-01-03", "fix: 2"),
|
|
69
|
+
cmt("a4", "2024-01-04", "fix: 3"),
|
|
70
|
+
cmt("a5", "2024-01-05", "fix: 4"),
|
|
71
|
+
cmt("a6", "2024-01-06", "fix: 5"),
|
|
72
|
+
cmt("a7", "2024-01-07", "feat: B"),
|
|
73
|
+
];
|
|
74
|
+
const drawdowns = detectDrawdowns(commits, { minLength: 3 });
|
|
75
|
+
expect(drawdowns).toHaveLength(1);
|
|
76
|
+
expect(drawdowns[0].length).toBe(5);
|
|
77
|
+
expect(drawdowns[0].tier).toBe("moderate");
|
|
78
|
+
expect(drawdowns[0].sampleFixes).toHaveLength(3);
|
|
79
|
+
});
|
|
80
|
+
it("detects multiple separate drawdowns", () => {
|
|
81
|
+
const commits = [
|
|
82
|
+
cmt("a1", "2024-01-01", "feat: A"),
|
|
83
|
+
cmt("a2", "2024-01-02", "fix: 1"),
|
|
84
|
+
cmt("a3", "2024-01-03", "fix: 2"),
|
|
85
|
+
cmt("a4", "2024-01-04", "fix: 3"),
|
|
86
|
+
cmt("a5", "2024-01-05", "feat: B"),
|
|
87
|
+
cmt("a6", "2024-01-06", "fix: 4"),
|
|
88
|
+
cmt("a7", "2024-01-07", "fix: 5"),
|
|
89
|
+
cmt("a8", "2024-01-08", "fix: 6"),
|
|
90
|
+
cmt("a9", "2024-01-09", "fix: 7"),
|
|
91
|
+
cmt("a10", "2024-01-10", "feat: C"),
|
|
92
|
+
];
|
|
93
|
+
const drawdowns = detectDrawdowns(commits, { minLength: 3 });
|
|
94
|
+
expect(drawdowns).toHaveLength(2);
|
|
95
|
+
});
|
|
96
|
+
it("respects fixRatio threshold (mixed chore/fix streaks)", () => {
|
|
97
|
+
const commits = [
|
|
98
|
+
cmt("a1", "2024-01-01", "feat: A"),
|
|
99
|
+
cmt("a2", "2024-01-02", "fix: 1"),
|
|
100
|
+
cmt("a3", "2024-01-03", "chore: bump deps"),
|
|
101
|
+
cmt("a4", "2024-01-04", "chore: lint config"),
|
|
102
|
+
cmt("a5", "2024-01-05", "feat: B"),
|
|
103
|
+
];
|
|
104
|
+
// 1/3 fix ratio — below default 0.5
|
|
105
|
+
expect(detectDrawdowns(commits, { minLength: 3, fixRatio: 0.5 })).toEqual([]);
|
|
106
|
+
expect(detectDrawdowns(commits, { minLength: 3, fixRatio: 0.3 })).toHaveLength(1);
|
|
107
|
+
});
|
|
108
|
+
it("sorts drawdowns by severity descending", () => {
|
|
109
|
+
const commits = [
|
|
110
|
+
// Drawdown 1: 4 fixes
|
|
111
|
+
cmt("a1", "2024-01-01", "feat: A"),
|
|
112
|
+
cmt("a2", "2024-01-02", "fix: 1"),
|
|
113
|
+
cmt("a3", "2024-01-03", "fix: 2"),
|
|
114
|
+
cmt("a4", "2024-01-04", "fix: 3"),
|
|
115
|
+
cmt("a5", "2024-01-05", "fix: 4"),
|
|
116
|
+
cmt("a6", "2024-01-06", "feat: B"),
|
|
117
|
+
// Drawdown 2: 8 fixes (more severe)
|
|
118
|
+
cmt("b1", "2024-02-01", "fix: 1"),
|
|
119
|
+
cmt("b2", "2024-02-02", "fix: 2"),
|
|
120
|
+
cmt("b3", "2024-02-03", "fix: 3"),
|
|
121
|
+
cmt("b4", "2024-02-04", "fix: 4"),
|
|
122
|
+
cmt("b5", "2024-02-05", "fix: 5"),
|
|
123
|
+
cmt("b6", "2024-02-06", "fix: 6"),
|
|
124
|
+
cmt("b7", "2024-02-07", "fix: 7"),
|
|
125
|
+
cmt("b8", "2024-02-08", "fix: 8"),
|
|
126
|
+
cmt("b9", "2024-02-09", "feat: C"),
|
|
127
|
+
];
|
|
128
|
+
const drawdowns = detectDrawdowns(commits, { minLength: 3 });
|
|
129
|
+
expect(drawdowns[0].length).toBe(8);
|
|
130
|
+
expect(drawdowns[1].length).toBe(4);
|
|
131
|
+
});
|
|
132
|
+
it("respects topN cap", () => {
|
|
133
|
+
const commits = [];
|
|
134
|
+
for (let i = 0; i < 30; i++) {
|
|
135
|
+
const day = String(i + 1).padStart(2, "0");
|
|
136
|
+
commits.push(cmt(`f${i}`, `2024-01-${day}`, "feat: x"));
|
|
137
|
+
commits.push(cmt(`x${i}`, `2024-01-${day}`, "fix: 1"));
|
|
138
|
+
commits.push(cmt(`y${i}`, `2024-01-${day}`, "fix: 2"));
|
|
139
|
+
commits.push(cmt(`z${i}`, `2024-01-${day}`, "fix: 3"));
|
|
140
|
+
}
|
|
141
|
+
expect(detectDrawdowns(commits, { minLength: 3, topN: 5 }).length).toBeLessThanOrEqual(5);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
describe("summarizeDrawdowns — repo-level metrics", () => {
|
|
145
|
+
it("computes drawdown fraction over repo lifespan", () => {
|
|
146
|
+
const commits = [
|
|
147
|
+
cmt("a1", "2024-01-01", "feat: A"),
|
|
148
|
+
cmt("a2", "2024-01-08", "fix: 1"), // 7 days into lifespan
|
|
149
|
+
cmt("a3", "2024-01-15", "fix: 2"),
|
|
150
|
+
cmt("a4", "2024-01-22", "fix: 3"),
|
|
151
|
+
cmt("a5", "2024-02-01", "feat: B"), // 31 days total
|
|
152
|
+
];
|
|
153
|
+
const drawdowns = detectDrawdowns(commits, { minLength: 3 });
|
|
154
|
+
const summary = summarizeDrawdowns(commits, drawdowns);
|
|
155
|
+
expect(summary.total).toBe(1);
|
|
156
|
+
expect(summary.longestStreak).toBe(3);
|
|
157
|
+
expect(summary.drawdownFraction).toBeGreaterThan(0);
|
|
158
|
+
expect(summary.drawdownFraction).toBeLessThan(1);
|
|
159
|
+
});
|
|
160
|
+
it("returns zero metrics for empty commits", () => {
|
|
161
|
+
const summary = summarizeDrawdowns([], []);
|
|
162
|
+
expect(summary.total).toBe(0);
|
|
163
|
+
expect(summary.drawdownFraction).toBe(0);
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
//# sourceMappingURL=drawdown.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawdown.test.js","sourceRoot":"","sources":["../../src/quant/drawdown.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mneme greek` — sensitivity analysis (Δ Γ Θ ν) for a codebase.
|
|
3
|
+
*
|
|
4
|
+
* Δ DELTA — sensitivity to the top contributor (% knowledge lost if X quits)
|
|
5
|
+
* Γ GAMMA — acceleration of risk (super-linear scaling of bug rate vs PR rate)
|
|
6
|
+
* Θ THETA — time decay (untouched files lose coverage over time)
|
|
7
|
+
* ν VEGA — sensitivity to dependency volatility (placeholder for now)
|
|
8
|
+
*
|
|
9
|
+
* Pure analysis. Delta + Gamma are required and computed from store data.
|
|
10
|
+
* Theta is best-effort (depends on coverage indexed). Vega returns null
|
|
11
|
+
* unless dependency manifest data is available — honestly.
|
|
12
|
+
*/
|
|
13
|
+
import type { MnemeStore } from "../store/sqlite.js";
|
|
14
|
+
export interface DeltaResult {
|
|
15
|
+
/** The author name. */
|
|
16
|
+
name: string;
|
|
17
|
+
/** Email. */
|
|
18
|
+
email: string;
|
|
19
|
+
/** Files where this author owns ≥ 75% of touches. */
|
|
20
|
+
ownedFiles: string[];
|
|
21
|
+
/** Approximate % of knowledge that walks out the door if they quit. */
|
|
22
|
+
knowledgeLossPct: number;
|
|
23
|
+
}
|
|
24
|
+
export declare function computeDelta(store: MnemeStore, opts?: {
|
|
25
|
+
topN?: number;
|
|
26
|
+
}): DeltaResult[];
|
|
27
|
+
export interface GammaResult {
|
|
28
|
+
/** Slope of (commits per week) → (fix-commits per week). */
|
|
29
|
+
riskAcceleration: number;
|
|
30
|
+
/** Sample size — number of weekly buckets used. */
|
|
31
|
+
weeks: number;
|
|
32
|
+
/** Plain-English interpretation. */
|
|
33
|
+
interpretation: string;
|
|
34
|
+
}
|
|
35
|
+
export declare function computeGamma(store: MnemeStore): GammaResult;
|
|
36
|
+
export interface ThetaResult {
|
|
37
|
+
/** Files untouched for > 6 months. */
|
|
38
|
+
staleFiles: number;
|
|
39
|
+
/** Average days since last touch across stale set. */
|
|
40
|
+
avgStaleDays: number;
|
|
41
|
+
/** Plain-English interpretation. */
|
|
42
|
+
interpretation: string;
|
|
43
|
+
}
|
|
44
|
+
export declare function computeTheta(store: MnemeStore, opts?: {
|
|
45
|
+
now?: Date;
|
|
46
|
+
}): ThetaResult;
|
|
47
|
+
export interface GreekReport {
|
|
48
|
+
delta: DeltaResult[];
|
|
49
|
+
gamma: GammaResult;
|
|
50
|
+
theta: ThetaResult;
|
|
51
|
+
}
|
|
52
|
+
export declare function computeGreeks(store: MnemeStore, opts?: {
|
|
53
|
+
now?: Date;
|
|
54
|
+
}): GreekReport;
|
|
55
|
+
//# sourceMappingURL=greek.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"greek.d.ts","sourceRoot":"","sources":["../../src/quant/greek.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIrD,MAAM,WAAW,WAAW;IAC1B,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa;IACb,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,uEAAuE;IACvE,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,WAAW,EAAE,CAwD3F;AAID,MAAM,WAAW,WAAW;IAC1B,4DAA4D;IAC5D,gBAAgB,EAAE,MAAM,CAAC;IACzB,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,cAAc,EAAE,MAAM,CAAC;CACxB;AAID,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CA0C3D;AA4BD,MAAM,WAAW,WAAW;IAC1B,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,YAAY,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,IAAI,CAAA;CAAO,GAAG,WAAW,CA6BtF;AAID,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,IAAI,CAAA;CAAO,GAAG,WAAW,CAMvF"}
|