circle-ir-ai 2.22.0 → 2.26.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/CHANGELOG.md +307 -0
- package/dist/agents/mastra/workflow.d.ts.map +1 -1
- package/dist/agents/mastra/workflow.js +41 -1
- package/dist/agents/mastra/workflow.js.map +1 -1
- package/dist/cache/discovery-cache.d.ts +71 -0
- package/dist/cache/discovery-cache.d.ts.map +1 -0
- package/dist/cache/discovery-cache.js +95 -0
- package/dist/cache/discovery-cache.js.map +1 -0
- package/dist/cache/tree-cache.d.ts +111 -0
- package/dist/cache/tree-cache.d.ts.map +1 -0
- package/dist/cache/tree-cache.js +171 -0
- package/dist/cache/tree-cache.js.map +1 -0
- package/dist/cache/verify-cache.d.ts +60 -0
- package/dist/cache/verify-cache.d.ts.map +1 -0
- package/dist/cache/verify-cache.js +103 -0
- package/dist/cache/verify-cache.js.map +1 -0
- package/dist/cluster/cluster.d.ts +174 -0
- package/dist/cluster/cluster.d.ts.map +1 -0
- package/dist/cluster/cluster.js +392 -0
- package/dist/cluster/cluster.js.map +1 -0
- package/dist/cluster/index.d.ts +11 -0
- package/dist/cluster/index.d.ts.map +1 -0
- package/dist/cluster/index.js +10 -0
- package/dist/cluster/index.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/llm/call-logger.d.ts +36 -0
- package/dist/llm/call-logger.d.ts.map +1 -1
- package/dist/llm/call-logger.js +36 -0
- package/dist/llm/call-logger.js.map +1 -1
- package/dist/llm/discovery.d.ts +1 -1
- package/dist/llm/discovery.d.ts.map +1 -1
- package/dist/llm/discovery.js +39 -0
- package/dist/llm/discovery.js.map +1 -1
- package/dist/llm/verification.d.ts +1 -1
- package/dist/llm/verification.d.ts.map +1 -1
- package/dist/llm/verification.js +39 -0
- package/dist/llm/verification.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cluster Layer — Foundation
|
|
3
|
+
*
|
|
4
|
+
* Top-of-pipeline file clustering (cognium-ai#154, P4 of epic #155).
|
|
5
|
+
* Groups files in a repo by their static structural fingerprint (CK
|
|
6
|
+
* metrics + import/annotation set) so downstream passes can apply
|
|
7
|
+
* per-cluster policy bundles ("library bootstrap" vs "controller
|
|
8
|
+
* surface" vs "data-access shim") instead of one-size-fits-all
|
|
9
|
+
* discovery/verification.
|
|
10
|
+
*
|
|
11
|
+
* This file ships the **foundation only**:
|
|
12
|
+
* - `extractClusterVector(circleIr)` — pull CK vector from analyze() output
|
|
13
|
+
* - `clusterFiles(inputs)` — deterministic k-medoids, returns
|
|
14
|
+
* `Map<filePath, clusterId>` per acceptance #1
|
|
15
|
+
* - distance functions (Euclidean on normalized CK + Jaccard on
|
|
16
|
+
* imports/annotations) + the k-medoids loop itself
|
|
17
|
+
* - `ClusterPolicy` type so downstream wiring can land in a
|
|
18
|
+
* follow-up without re-declaring shape
|
|
19
|
+
*
|
|
20
|
+
* **Explicitly out of scope here** (tracked as follow-up tickets):
|
|
21
|
+
* - `meta.json.files[*].clusterId` field — needs scan-emit schema
|
|
22
|
+
* migration (Acceptance #3)
|
|
23
|
+
* - top-100 HIGH/CRIT reduction validation (Acceptance #4)
|
|
24
|
+
* - CWE-Bench-Java regression check (Acceptance #5)
|
|
25
|
+
* - `--cluster-policy <profile>` CLI flag in cognium-ai
|
|
26
|
+
* (Acceptance #6)
|
|
27
|
+
* - LLM cluster labeling pass (optional future per the issue)
|
|
28
|
+
*
|
|
29
|
+
* The split is deliberate: P1-P3 of epic #155 were single-shot
|
|
30
|
+
* cache wins; P4's policy bundles + the two benchmark validation
|
|
31
|
+
* gates need empirical tuning that can't complete in a single
|
|
32
|
+
* release cycle. Foundation-first lets cognium-ai start consuming
|
|
33
|
+
* `clusterFiles()` as an opaque grouping signal while the policy
|
|
34
|
+
* resolver is iterated separately.
|
|
35
|
+
*
|
|
36
|
+
* **Determinism:** k-medoids is seeded from a digest of (sorted
|
|
37
|
+
* file paths || vector signature) so re-runs on the same input
|
|
38
|
+
* produce the same cluster assignments. Tie-breaking on equal
|
|
39
|
+
* distances falls back to lexicographic path order.
|
|
40
|
+
*/
|
|
41
|
+
import type { CircleIR } from 'circle-ir';
|
|
42
|
+
/**
|
|
43
|
+
* Per-file structural fingerprint used as the clustering signal.
|
|
44
|
+
* CK metrics default to 0 when circle-ir's metric pass didn't run
|
|
45
|
+
* (e.g. procedural-only files, languages without classes).
|
|
46
|
+
*/
|
|
47
|
+
export interface ClusterVector {
|
|
48
|
+
cbo: number;
|
|
49
|
+
rfc: number;
|
|
50
|
+
lcom: number;
|
|
51
|
+
dit: number;
|
|
52
|
+
noc: number;
|
|
53
|
+
wmc: number;
|
|
54
|
+
imports: string[];
|
|
55
|
+
publicSurface: number;
|
|
56
|
+
annotations: string[];
|
|
57
|
+
}
|
|
58
|
+
export interface ClusterInput {
|
|
59
|
+
filePath: string;
|
|
60
|
+
vector: ClusterVector;
|
|
61
|
+
}
|
|
62
|
+
export interface ClusterAssignment {
|
|
63
|
+
filePath: string;
|
|
64
|
+
clusterId: number;
|
|
65
|
+
}
|
|
66
|
+
export interface ClusterResult {
|
|
67
|
+
k: number;
|
|
68
|
+
assignments: ClusterAssignment[];
|
|
69
|
+
/** Medoid file path per cluster id (index = clusterId). */
|
|
70
|
+
medoids: string[];
|
|
71
|
+
/** Iterations until convergence (for tuning visibility). */
|
|
72
|
+
iterations: number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Downstream policy bundle attached to a cluster. Shape locked here
|
|
76
|
+
* so wiring tickets can land without re-negotiating the contract;
|
|
77
|
+
* default policy ("application", everything on) is what consumers
|
|
78
|
+
* should apply until cluster-specific overrides ship.
|
|
79
|
+
*/
|
|
80
|
+
export type ContextProfile = 'application' | 'library' | 'framework' | 'tool';
|
|
81
|
+
export interface ClusterPolicy {
|
|
82
|
+
contextProfile: ContextProfile;
|
|
83
|
+
/** Discovery source kinds permitted; empty array = all. */
|
|
84
|
+
sourceWhitelist: string[];
|
|
85
|
+
/** Verification sink classes permitted; empty array = all. */
|
|
86
|
+
sinkWhitelist: string[];
|
|
87
|
+
/** When false, downstream LLM passes skip this cluster entirely. */
|
|
88
|
+
llmEnabled: boolean;
|
|
89
|
+
}
|
|
90
|
+
export declare const DEFAULT_CLUSTER_POLICY: ClusterPolicy;
|
|
91
|
+
/**
|
|
92
|
+
* Extract a ClusterVector from a single-file `CircleIR` analyze()
|
|
93
|
+
* result. Missing metrics default to 0 — the cluster vector is
|
|
94
|
+
* structural, so a procedural file with no CK numbers will land
|
|
95
|
+
* in the "low-complexity" cluster naturally (it's a valid signal,
|
|
96
|
+
* not missing data).
|
|
97
|
+
*/
|
|
98
|
+
export declare function extractClusterVector(circleIr: CircleIR): ClusterVector;
|
|
99
|
+
/**
|
|
100
|
+
* Per-axis max-normalize the CK + publicSurface scalars across the
|
|
101
|
+
* input set. Max-normalize (rather than z-score) is deliberate:
|
|
102
|
+
* cluster boundaries should be robust to outliers (one god-class
|
|
103
|
+
* with WMC=400 shouldn't squash everything else into the same
|
|
104
|
+
* cluster), and max-normalize gives a clean [0,1] domain that
|
|
105
|
+
* combines naturally with Jaccard.
|
|
106
|
+
*
|
|
107
|
+
* Returns the maxima so callers can normalize new vectors against
|
|
108
|
+
* the same scale (e.g. for the k-medoids loop on the same set).
|
|
109
|
+
*/
|
|
110
|
+
export declare function computeNormalization(inputs: ClusterInput[]): {
|
|
111
|
+
cboMax: number;
|
|
112
|
+
rfcMax: number;
|
|
113
|
+
lcomMax: number;
|
|
114
|
+
ditMax: number;
|
|
115
|
+
nocMax: number;
|
|
116
|
+
wmcMax: number;
|
|
117
|
+
publicSurfaceMax: number;
|
|
118
|
+
};
|
|
119
|
+
/** Euclidean distance on the max-normalized CK + publicSurface scalars. */
|
|
120
|
+
export declare function euclideanCkDistance(a: ClusterVector, b: ClusterVector, norm: ReturnType<typeof computeNormalization>): number;
|
|
121
|
+
/**
|
|
122
|
+
* Jaccard distance on two string sets (1 - |intersection|/|union|).
|
|
123
|
+
* Returns 0 when both sets are empty (semantically: nothing
|
|
124
|
+
* distinguishes them on this axis).
|
|
125
|
+
*/
|
|
126
|
+
export declare function jaccardDistance(a: string[], b: string[]): number;
|
|
127
|
+
/**
|
|
128
|
+
* Combined per-pair distance. Weights mirror the issue's signal
|
|
129
|
+
* vector ordering (CK is the primary signal; imports + annotations
|
|
130
|
+
* are tiebreakers). Total is in [0,1] so it composes cleanly with
|
|
131
|
+
* other metric-space algorithms.
|
|
132
|
+
*
|
|
133
|
+
* Weights chosen to sum to 1:
|
|
134
|
+
* 0.6 — CK + publicSurface Euclidean (clamped to 1 by sqrt of 7
|
|
135
|
+
* normalized components, since each (a-b)/max is in [-1,1])
|
|
136
|
+
* 0.2 — imports Jaccard
|
|
137
|
+
* 0.2 — annotations Jaccard
|
|
138
|
+
*
|
|
139
|
+
* Euclidean is divided by sqrt(7) to renormalize to [0,1] before
|
|
140
|
+
* weighting — without this, the CK term can exceed 1 and the total
|
|
141
|
+
* stops being a proper [0,1] distance.
|
|
142
|
+
*/
|
|
143
|
+
export declare function mixedDistance(a: ClusterVector, b: ClusterVector, norm: ReturnType<typeof computeNormalization>): number;
|
|
144
|
+
interface KMedoidsOptions {
|
|
145
|
+
/** Desired cluster count. Clamped to `[1, inputs.length]`. */
|
|
146
|
+
k: number;
|
|
147
|
+
/** Maximum iterations before bailing. Default 50. */
|
|
148
|
+
maxIter?: number;
|
|
149
|
+
/** Override the deterministic seed (test-only). */
|
|
150
|
+
seed?: number;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* PAM-lite k-medoids on `inputs`.
|
|
154
|
+
*
|
|
155
|
+
* 1. Seed selection ("build" phase): pick the medoid that minimizes
|
|
156
|
+
* total distance to all points, then iteratively pick the point
|
|
157
|
+
* that maximizes minimum distance to existing medoids. This is
|
|
158
|
+
* deterministic given the seed and degenerates gracefully when
|
|
159
|
+
* `inputs.length <= k`.
|
|
160
|
+
* 2. Assignment: each point joins its closest medoid (lex path
|
|
161
|
+
* tiebreak on equal distances).
|
|
162
|
+
* 3. Swap phase: for each cluster, find the point that minimizes
|
|
163
|
+
* intra-cluster distance and promote it to medoid. Repeat until
|
|
164
|
+
* no medoid changes (or `maxIter` hits).
|
|
165
|
+
*
|
|
166
|
+
* Complexity is O(n^2 * iter) on the distance matrix. For the
|
|
167
|
+
* top-100 sweep (n ≈ 5000 per repo at the high end) this is ~25M
|
|
168
|
+
* pairwise computations per iteration — fine for the <2s budget
|
|
169
|
+
* in Acceptance #2 because distances are scalar arithmetic on
|
|
170
|
+
* a 9-dim vector.
|
|
171
|
+
*/
|
|
172
|
+
export declare function clusterFiles(inputs: ClusterInput[], options: KMedoidsOptions): ClusterResult;
|
|
173
|
+
export {};
|
|
174
|
+
//# sourceMappingURL=cluster.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cluster.d.ts","sourceRoot":"","sources":["../../src/cluster/cluster.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAe,MAAM,WAAW,CAAC;AAMvD;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,CAAC,EAAE,MAAM,CAAC;IACV,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,2DAA2D;IAC3D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,CAAC;AAE9E,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,cAAc,CAAC;IAC/B,2DAA2D;IAC3D,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,8DAA8D;IAC9D,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,oEAAoE;IACpE,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,eAAO,MAAM,sBAAsB,EAAE,aAKpC,CAAC;AAsBF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,GAAG,aAAa,CAyDtE;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAYA;AAED,2EAA2E;AAC3E,wBAAgB,mBAAmB,CACjC,CAAC,EAAE,aAAa,EAChB,CAAC,EAAE,aAAa,EAChB,IAAI,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,GAC5C,MAAM,CAWR;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAShE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAC3B,CAAC,EAAE,aAAa,EAChB,CAAC,EAAE,aAAa,EAChB,IAAI,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,GAC5C,MAAM,CAKR;AAwCD,UAAU,eAAe;IACvB,8DAA8D;IAC9D,CAAC,EAAE,MAAM,CAAC;IACV,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,YAAY,EAAE,EACtB,OAAO,EAAE,eAAe,GACvB,aAAa,CAsJf"}
|
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cluster Layer — Foundation
|
|
3
|
+
*
|
|
4
|
+
* Top-of-pipeline file clustering (cognium-ai#154, P4 of epic #155).
|
|
5
|
+
* Groups files in a repo by their static structural fingerprint (CK
|
|
6
|
+
* metrics + import/annotation set) so downstream passes can apply
|
|
7
|
+
* per-cluster policy bundles ("library bootstrap" vs "controller
|
|
8
|
+
* surface" vs "data-access shim") instead of one-size-fits-all
|
|
9
|
+
* discovery/verification.
|
|
10
|
+
*
|
|
11
|
+
* This file ships the **foundation only**:
|
|
12
|
+
* - `extractClusterVector(circleIr)` — pull CK vector from analyze() output
|
|
13
|
+
* - `clusterFiles(inputs)` — deterministic k-medoids, returns
|
|
14
|
+
* `Map<filePath, clusterId>` per acceptance #1
|
|
15
|
+
* - distance functions (Euclidean on normalized CK + Jaccard on
|
|
16
|
+
* imports/annotations) + the k-medoids loop itself
|
|
17
|
+
* - `ClusterPolicy` type so downstream wiring can land in a
|
|
18
|
+
* follow-up without re-declaring shape
|
|
19
|
+
*
|
|
20
|
+
* **Explicitly out of scope here** (tracked as follow-up tickets):
|
|
21
|
+
* - `meta.json.files[*].clusterId` field — needs scan-emit schema
|
|
22
|
+
* migration (Acceptance #3)
|
|
23
|
+
* - top-100 HIGH/CRIT reduction validation (Acceptance #4)
|
|
24
|
+
* - CWE-Bench-Java regression check (Acceptance #5)
|
|
25
|
+
* - `--cluster-policy <profile>` CLI flag in cognium-ai
|
|
26
|
+
* (Acceptance #6)
|
|
27
|
+
* - LLM cluster labeling pass (optional future per the issue)
|
|
28
|
+
*
|
|
29
|
+
* The split is deliberate: P1-P3 of epic #155 were single-shot
|
|
30
|
+
* cache wins; P4's policy bundles + the two benchmark validation
|
|
31
|
+
* gates need empirical tuning that can't complete in a single
|
|
32
|
+
* release cycle. Foundation-first lets cognium-ai start consuming
|
|
33
|
+
* `clusterFiles()` as an opaque grouping signal while the policy
|
|
34
|
+
* resolver is iterated separately.
|
|
35
|
+
*
|
|
36
|
+
* **Determinism:** k-medoids is seeded from a digest of (sorted
|
|
37
|
+
* file paths || vector signature) so re-runs on the same input
|
|
38
|
+
* produce the same cluster assignments. Tie-breaking on equal
|
|
39
|
+
* distances falls back to lexicographic path order.
|
|
40
|
+
*/
|
|
41
|
+
import * as crypto from 'crypto';
|
|
42
|
+
export const DEFAULT_CLUSTER_POLICY = {
|
|
43
|
+
contextProfile: 'application',
|
|
44
|
+
sourceWhitelist: [],
|
|
45
|
+
sinkWhitelist: [],
|
|
46
|
+
llmEnabled: true,
|
|
47
|
+
};
|
|
48
|
+
// ───────────────────────────────────────────────────────────────────
|
|
49
|
+
// CK vector extraction
|
|
50
|
+
// ───────────────────────────────────────────────────────────────────
|
|
51
|
+
/**
|
|
52
|
+
* Names emitted by circle-ir's CK metric passes. Mirrored from
|
|
53
|
+
* the JSDoc on `MetricValue` in circle-ir's public type surface
|
|
54
|
+
* (canonical: "CBO" | "RFC" | "LCOM" | "DIT" | "NOC" | "WMC").
|
|
55
|
+
* Matching is case-insensitive because metric-pass authors have
|
|
56
|
+
* historically used both casings.
|
|
57
|
+
*/
|
|
58
|
+
const CK_METRIC_KEYS = ['CBO', 'RFC', 'LCOM', 'DIT', 'NOC', 'WMC'];
|
|
59
|
+
function findMetric(metrics, name) {
|
|
60
|
+
if (!metrics)
|
|
61
|
+
return 0;
|
|
62
|
+
const lower = name.toLowerCase();
|
|
63
|
+
const hit = metrics.find((m) => m.name.toLowerCase() === lower);
|
|
64
|
+
return hit ? hit.value : 0;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Extract a ClusterVector from a single-file `CircleIR` analyze()
|
|
68
|
+
* result. Missing metrics default to 0 — the cluster vector is
|
|
69
|
+
* structural, so a procedural file with no CK numbers will land
|
|
70
|
+
* in the "low-complexity" cluster naturally (it's a valid signal,
|
|
71
|
+
* not missing data).
|
|
72
|
+
*/
|
|
73
|
+
export function extractClusterVector(circleIr) {
|
|
74
|
+
const metrics = circleIr.metrics?.metrics;
|
|
75
|
+
// Import package signatures — keep top-2 segments (e.g.
|
|
76
|
+
// `java.util.List` → `java.util`) so unrelated imports of
|
|
77
|
+
// different leaf types in the same package don't artificially
|
|
78
|
+
// increase Jaccard distance. circle-ir's `ImportInfo` carries
|
|
79
|
+
// `from_package` (the canonical package path) and falls back to
|
|
80
|
+
// `imported_name` when `from_package` is null (wildcard / default
|
|
81
|
+
// imports).
|
|
82
|
+
const imports = Array.from(new Set((circleIr.imports ?? [])
|
|
83
|
+
.map((imp) => {
|
|
84
|
+
const raw = imp.from_package ?? imp.imported_name ?? '';
|
|
85
|
+
const parts = raw.split('.');
|
|
86
|
+
return parts.length >= 2 ? parts.slice(0, 2).join('.') : raw;
|
|
87
|
+
})
|
|
88
|
+
.filter((s) => s.length > 0)));
|
|
89
|
+
// Class-level annotations (Java: `@RestController`, `@Service`,
|
|
90
|
+
// `@Entity`; Python: `@app.route` would surface here if circle-ir
|
|
91
|
+
// attaches it to the class node). Pulled from `types[*].annotations`.
|
|
92
|
+
const annotations = Array.from(new Set((circleIr.types ?? [])
|
|
93
|
+
.flatMap((t) => t.annotations ?? [])
|
|
94
|
+
.filter((s) => typeof s === 'string' && s.length > 0)));
|
|
95
|
+
// Public surface = count of types + methods that aren't explicitly
|
|
96
|
+
// marked private. `TypeInfo` has no visibility field in circle-ir's
|
|
97
|
+
// surface (all top-level types count as "public-ish" for clustering
|
|
98
|
+
// purposes); methods carry `modifiers: string[]` from which we pull
|
|
99
|
+
// the visibility token.
|
|
100
|
+
let publicSurface = 0;
|
|
101
|
+
for (const t of circleIr.types ?? []) {
|
|
102
|
+
publicSurface++;
|
|
103
|
+
for (const m of t.methods ?? []) {
|
|
104
|
+
if (!(m.modifiers ?? []).includes('private'))
|
|
105
|
+
publicSurface++;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
cbo: findMetric(metrics, 'CBO'),
|
|
110
|
+
rfc: findMetric(metrics, 'RFC'),
|
|
111
|
+
lcom: findMetric(metrics, 'LCOM'),
|
|
112
|
+
dit: findMetric(metrics, 'DIT'),
|
|
113
|
+
noc: findMetric(metrics, 'NOC'),
|
|
114
|
+
wmc: findMetric(metrics, 'WMC'),
|
|
115
|
+
imports,
|
|
116
|
+
publicSurface,
|
|
117
|
+
annotations,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
// ───────────────────────────────────────────────────────────────────
|
|
121
|
+
// Distance functions
|
|
122
|
+
// ───────────────────────────────────────────────────────────────────
|
|
123
|
+
/**
|
|
124
|
+
* Per-axis max-normalize the CK + publicSurface scalars across the
|
|
125
|
+
* input set. Max-normalize (rather than z-score) is deliberate:
|
|
126
|
+
* cluster boundaries should be robust to outliers (one god-class
|
|
127
|
+
* with WMC=400 shouldn't squash everything else into the same
|
|
128
|
+
* cluster), and max-normalize gives a clean [0,1] domain that
|
|
129
|
+
* combines naturally with Jaccard.
|
|
130
|
+
*
|
|
131
|
+
* Returns the maxima so callers can normalize new vectors against
|
|
132
|
+
* the same scale (e.g. for the k-medoids loop on the same set).
|
|
133
|
+
*/
|
|
134
|
+
export function computeNormalization(inputs) {
|
|
135
|
+
const max = (sel) => Math.max(1, ...inputs.map((i) => sel(i.vector)));
|
|
136
|
+
return {
|
|
137
|
+
cboMax: max((v) => v.cbo),
|
|
138
|
+
rfcMax: max((v) => v.rfc),
|
|
139
|
+
lcomMax: max((v) => v.lcom),
|
|
140
|
+
ditMax: max((v) => v.dit),
|
|
141
|
+
nocMax: max((v) => v.noc),
|
|
142
|
+
wmcMax: max((v) => v.wmc),
|
|
143
|
+
publicSurfaceMax: max((v) => v.publicSurface),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/** Euclidean distance on the max-normalized CK + publicSurface scalars. */
|
|
147
|
+
export function euclideanCkDistance(a, b, norm) {
|
|
148
|
+
const dx = [
|
|
149
|
+
(a.cbo - b.cbo) / norm.cboMax,
|
|
150
|
+
(a.rfc - b.rfc) / norm.rfcMax,
|
|
151
|
+
(a.lcom - b.lcom) / norm.lcomMax,
|
|
152
|
+
(a.dit - b.dit) / norm.ditMax,
|
|
153
|
+
(a.noc - b.noc) / norm.nocMax,
|
|
154
|
+
(a.wmc - b.wmc) / norm.wmcMax,
|
|
155
|
+
(a.publicSurface - b.publicSurface) / norm.publicSurfaceMax,
|
|
156
|
+
];
|
|
157
|
+
return Math.sqrt(dx.reduce((acc, x) => acc + x * x, 0));
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Jaccard distance on two string sets (1 - |intersection|/|union|).
|
|
161
|
+
* Returns 0 when both sets are empty (semantically: nothing
|
|
162
|
+
* distinguishes them on this axis).
|
|
163
|
+
*/
|
|
164
|
+
export function jaccardDistance(a, b) {
|
|
165
|
+
if (a.length === 0 && b.length === 0)
|
|
166
|
+
return 0;
|
|
167
|
+
const sa = new Set(a);
|
|
168
|
+
const sb = new Set(b);
|
|
169
|
+
let intersect = 0;
|
|
170
|
+
for (const x of sa)
|
|
171
|
+
if (sb.has(x))
|
|
172
|
+
intersect++;
|
|
173
|
+
const union = sa.size + sb.size - intersect;
|
|
174
|
+
if (union === 0)
|
|
175
|
+
return 0;
|
|
176
|
+
return 1 - intersect / union;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Combined per-pair distance. Weights mirror the issue's signal
|
|
180
|
+
* vector ordering (CK is the primary signal; imports + annotations
|
|
181
|
+
* are tiebreakers). Total is in [0,1] so it composes cleanly with
|
|
182
|
+
* other metric-space algorithms.
|
|
183
|
+
*
|
|
184
|
+
* Weights chosen to sum to 1:
|
|
185
|
+
* 0.6 — CK + publicSurface Euclidean (clamped to 1 by sqrt of 7
|
|
186
|
+
* normalized components, since each (a-b)/max is in [-1,1])
|
|
187
|
+
* 0.2 — imports Jaccard
|
|
188
|
+
* 0.2 — annotations Jaccard
|
|
189
|
+
*
|
|
190
|
+
* Euclidean is divided by sqrt(7) to renormalize to [0,1] before
|
|
191
|
+
* weighting — without this, the CK term can exceed 1 and the total
|
|
192
|
+
* stops being a proper [0,1] distance.
|
|
193
|
+
*/
|
|
194
|
+
export function mixedDistance(a, b, norm) {
|
|
195
|
+
const ck = euclideanCkDistance(a, b, norm) / Math.sqrt(7);
|
|
196
|
+
const importsD = jaccardDistance(a.imports, b.imports);
|
|
197
|
+
const annotationsD = jaccardDistance(a.annotations, b.annotations);
|
|
198
|
+
return 0.6 * ck + 0.2 * importsD + 0.2 * annotationsD;
|
|
199
|
+
}
|
|
200
|
+
// ───────────────────────────────────────────────────────────────────
|
|
201
|
+
// Seeded PRNG (deterministic across runs)
|
|
202
|
+
// ───────────────────────────────────────────────────────────────────
|
|
203
|
+
/**
|
|
204
|
+
* Mulberry32 — fast, well-distributed seeded PRNG. We don't need
|
|
205
|
+
* cryptographic randomness here, just reproducibility across runs
|
|
206
|
+
* for the same input set. Seed is derived from a digest of the
|
|
207
|
+
* sorted (path || vector) signatures so adding/removing files
|
|
208
|
+
* changes the seed but reordering inputs does not.
|
|
209
|
+
*/
|
|
210
|
+
function mulberry32(seed) {
|
|
211
|
+
let s = seed >>> 0;
|
|
212
|
+
return () => {
|
|
213
|
+
s = (s + 0x6d2b79f5) >>> 0;
|
|
214
|
+
let t = s;
|
|
215
|
+
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
216
|
+
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
217
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
function deriveSeed(inputs) {
|
|
221
|
+
const sig = inputs
|
|
222
|
+
.map((i) => `${i.filePath}\0${i.vector.cbo},${i.vector.rfc},${i.vector.lcom},${i.vector.dit},${i.vector.noc},${i.vector.wmc},${i.vector.publicSurface}`)
|
|
223
|
+
.sort()
|
|
224
|
+
.join('|');
|
|
225
|
+
const hash = crypto.createHash('sha256').update(sig).digest();
|
|
226
|
+
return hash.readUInt32BE(0);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* PAM-lite k-medoids on `inputs`.
|
|
230
|
+
*
|
|
231
|
+
* 1. Seed selection ("build" phase): pick the medoid that minimizes
|
|
232
|
+
* total distance to all points, then iteratively pick the point
|
|
233
|
+
* that maximizes minimum distance to existing medoids. This is
|
|
234
|
+
* deterministic given the seed and degenerates gracefully when
|
|
235
|
+
* `inputs.length <= k`.
|
|
236
|
+
* 2. Assignment: each point joins its closest medoid (lex path
|
|
237
|
+
* tiebreak on equal distances).
|
|
238
|
+
* 3. Swap phase: for each cluster, find the point that minimizes
|
|
239
|
+
* intra-cluster distance and promote it to medoid. Repeat until
|
|
240
|
+
* no medoid changes (or `maxIter` hits).
|
|
241
|
+
*
|
|
242
|
+
* Complexity is O(n^2 * iter) on the distance matrix. For the
|
|
243
|
+
* top-100 sweep (n ≈ 5000 per repo at the high end) this is ~25M
|
|
244
|
+
* pairwise computations per iteration — fine for the <2s budget
|
|
245
|
+
* in Acceptance #2 because distances are scalar arithmetic on
|
|
246
|
+
* a 9-dim vector.
|
|
247
|
+
*/
|
|
248
|
+
export function clusterFiles(inputs, options) {
|
|
249
|
+
const k = Math.max(1, Math.min(options.k, inputs.length));
|
|
250
|
+
const maxIter = options.maxIter ?? 50;
|
|
251
|
+
if (inputs.length === 0) {
|
|
252
|
+
return { k: 0, assignments: [], medoids: [], iterations: 0 };
|
|
253
|
+
}
|
|
254
|
+
// Sort by path so ties are broken lexicographically regardless of
|
|
255
|
+
// input order.
|
|
256
|
+
const sorted = [...inputs].sort((a, b) => a.filePath.localeCompare(b.filePath));
|
|
257
|
+
const n = sorted.length;
|
|
258
|
+
const norm = computeNormalization(sorted);
|
|
259
|
+
// Precompute distance matrix (symmetric, diagonal zero).
|
|
260
|
+
const dist = Array.from({ length: n }, () => new Array(n).fill(0));
|
|
261
|
+
for (let i = 0; i < n; i++) {
|
|
262
|
+
for (let j = i + 1; j < n; j++) {
|
|
263
|
+
const d = mixedDistance(sorted[i].vector, sorted[j].vector, norm);
|
|
264
|
+
dist[i][j] = d;
|
|
265
|
+
dist[j][i] = d;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// Build phase — deterministic seed init.
|
|
269
|
+
const seed = options.seed ?? deriveSeed(sorted);
|
|
270
|
+
const rng = mulberry32(seed);
|
|
271
|
+
const medoidIdx = [];
|
|
272
|
+
// First medoid: minimize total distance to all points (1-medoid PAM).
|
|
273
|
+
let bestSum = Infinity;
|
|
274
|
+
let bestIdx = 0;
|
|
275
|
+
for (let i = 0; i < n; i++) {
|
|
276
|
+
let sum = 0;
|
|
277
|
+
for (let j = 0; j < n; j++)
|
|
278
|
+
sum += dist[i][j];
|
|
279
|
+
if (sum < bestSum || (sum === bestSum && sorted[i].filePath < sorted[bestIdx].filePath)) {
|
|
280
|
+
bestSum = sum;
|
|
281
|
+
bestIdx = i;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
medoidIdx.push(bestIdx);
|
|
285
|
+
// Remaining medoids: maximize min-distance to existing medoids.
|
|
286
|
+
// RNG breaks ties on equally-far candidates for deterministic but
|
|
287
|
+
// non-degenerate seeding when the set has structural symmetry.
|
|
288
|
+
while (medoidIdx.length < k) {
|
|
289
|
+
let bestPick = -1;
|
|
290
|
+
let bestMinDist = -1;
|
|
291
|
+
const candidates = [];
|
|
292
|
+
for (let i = 0; i < n; i++) {
|
|
293
|
+
if (medoidIdx.includes(i))
|
|
294
|
+
continue;
|
|
295
|
+
let minD = Infinity;
|
|
296
|
+
for (const m of medoidIdx) {
|
|
297
|
+
if (dist[i][m] < minD)
|
|
298
|
+
minD = dist[i][m];
|
|
299
|
+
}
|
|
300
|
+
if (minD > bestMinDist) {
|
|
301
|
+
bestMinDist = minD;
|
|
302
|
+
bestPick = i;
|
|
303
|
+
candidates.length = 0;
|
|
304
|
+
candidates.push(i);
|
|
305
|
+
}
|
|
306
|
+
else if (minD === bestMinDist) {
|
|
307
|
+
candidates.push(i);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
if (bestPick === -1)
|
|
311
|
+
break;
|
|
312
|
+
// Tiebreak: lex-first wins; if rng() < 0.5, allow a randomized
|
|
313
|
+
// alternative from the tied set. This preserves determinism
|
|
314
|
+
// (same seed → same pick) while avoiding pathological pile-ups
|
|
315
|
+
// on highly-symmetric inputs.
|
|
316
|
+
if (candidates.length > 1 && rng() < 0.5) {
|
|
317
|
+
candidates.sort((a, b) => sorted[a].filePath.localeCompare(sorted[b].filePath));
|
|
318
|
+
bestPick = candidates[Math.floor(rng() * candidates.length)];
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
// Default: lex-first.
|
|
322
|
+
bestPick = candidates.reduce((best, c) => (sorted[c].filePath < sorted[best].filePath ? c : best), candidates[0]);
|
|
323
|
+
}
|
|
324
|
+
medoidIdx.push(bestPick);
|
|
325
|
+
}
|
|
326
|
+
// Iterate: assign → swap → check convergence.
|
|
327
|
+
let assignment = new Array(n).fill(0);
|
|
328
|
+
let iterations = 0;
|
|
329
|
+
for (let iter = 0; iter < maxIter; iter++) {
|
|
330
|
+
iterations = iter + 1;
|
|
331
|
+
// Assign each point to closest medoid (lex tiebreak via medoid order).
|
|
332
|
+
for (let i = 0; i < n; i++) {
|
|
333
|
+
let bestC = 0;
|
|
334
|
+
let bestD = dist[i][medoidIdx[0]];
|
|
335
|
+
for (let c = 1; c < medoidIdx.length; c++) {
|
|
336
|
+
const d = dist[i][medoidIdx[c]];
|
|
337
|
+
if (d < bestD ||
|
|
338
|
+
(d === bestD && sorted[medoidIdx[c]].filePath < sorted[medoidIdx[bestC]].filePath)) {
|
|
339
|
+
bestD = d;
|
|
340
|
+
bestC = c;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
assignment[i] = bestC;
|
|
344
|
+
}
|
|
345
|
+
// Swap: for each cluster, find the point that minimizes
|
|
346
|
+
// intra-cluster distance and promote it.
|
|
347
|
+
const newMedoids = [...medoidIdx];
|
|
348
|
+
for (let c = 0; c < medoidIdx.length; c++) {
|
|
349
|
+
const members = [];
|
|
350
|
+
for (let i = 0; i < n; i++)
|
|
351
|
+
if (assignment[i] === c)
|
|
352
|
+
members.push(i);
|
|
353
|
+
if (members.length === 0)
|
|
354
|
+
continue;
|
|
355
|
+
let bestM = newMedoids[c];
|
|
356
|
+
let bestCost = Infinity;
|
|
357
|
+
for (const m of members) {
|
|
358
|
+
let cost = 0;
|
|
359
|
+
for (const other of members)
|
|
360
|
+
cost += dist[m][other];
|
|
361
|
+
if (cost < bestCost || (cost === bestCost && sorted[m].filePath < sorted[bestM].filePath)) {
|
|
362
|
+
bestCost = cost;
|
|
363
|
+
bestM = m;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
newMedoids[c] = bestM;
|
|
367
|
+
}
|
|
368
|
+
// Check convergence (medoid set stable).
|
|
369
|
+
let changed = false;
|
|
370
|
+
for (let c = 0; c < newMedoids.length; c++) {
|
|
371
|
+
if (newMedoids[c] !== medoidIdx[c]) {
|
|
372
|
+
changed = true;
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
medoidIdx.length = 0;
|
|
377
|
+
medoidIdx.push(...newMedoids);
|
|
378
|
+
if (!changed)
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
const assignments = sorted.map((inp, i) => ({
|
|
382
|
+
filePath: inp.filePath,
|
|
383
|
+
clusterId: assignment[i],
|
|
384
|
+
}));
|
|
385
|
+
return {
|
|
386
|
+
k: medoidIdx.length,
|
|
387
|
+
assignments,
|
|
388
|
+
medoids: medoidIdx.map((i) => sorted[i].filePath),
|
|
389
|
+
iterations,
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
//# sourceMappingURL=cluster.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cluster.js","sourceRoot":"","sources":["../../src/cluster/cluster.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cluster layer public surface.
|
|
3
|
+
*
|
|
4
|
+
* Foundation only (cognium-ai#154, P4 of epic #155). Re-exports the
|
|
5
|
+
* primitives that downstream wiring tickets (meta.json schema, CLI
|
|
6
|
+
* flag, benchmark validation) will consume — see `cluster.ts`
|
|
7
|
+
* file-header for the scope split.
|
|
8
|
+
*/
|
|
9
|
+
export { clusterFiles, extractClusterVector, computeNormalization, euclideanCkDistance, jaccardDistance, mixedDistance, DEFAULT_CLUSTER_POLICY, } from './cluster.js';
|
|
10
|
+
export type { ClusterVector, ClusterInput, ClusterAssignment, ClusterResult, ClusterPolicy, ContextProfile, } from './cluster.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cluster/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,sBAAsB,GACvB,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,cAAc,GACf,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cluster layer public surface.
|
|
3
|
+
*
|
|
4
|
+
* Foundation only (cognium-ai#154, P4 of epic #155). Re-exports the
|
|
5
|
+
* primitives that downstream wiring tickets (meta.json schema, CLI
|
|
6
|
+
* flag, benchmark validation) will consume — see `cluster.ts`
|
|
7
|
+
* file-header for the scope split.
|
|
8
|
+
*/
|
|
9
|
+
export { clusterFiles, extractClusterVector, computeNormalization, euclideanCkDistance, jaccardDistance, mixedDistance, DEFAULT_CLUSTER_POLICY, } from './cluster.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cluster/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,sBAAsB,GACvB,MAAM,cAAc,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -55,4 +55,5 @@ export { analyzeComponents, enrichComponent, enrichComponents, clusterComponents
|
|
|
55
55
|
export { summarizeFunction, summarizeAllFunctions, summarizeModule, detectRole, type FunctionEffect, type SideEffect, type SideEffectKind, type ModuleSummary, type ModuleRole, type UnderstandOptions, type UnderstandResult, } from './understand/index.js';
|
|
56
56
|
export { analyzeSpecGap, parseSpecMd, type SpecGapResult, type SpecGapOptions, type RequirementMatch, type UncoveredRequirement, type UndocumentedBehavior, } from './spec-gap/index.js';
|
|
57
57
|
export { loadCogniumConfig, convertCogniumConfigToPassOptions, type CogniumConfig, type Suppression, } from './config/cognium-config.js';
|
|
58
|
+
export { clusterFiles, extractClusterVector, computeNormalization, euclideanCkDistance, jaccardDistance, mixedDistance, DEFAULT_CLUSTER_POLICY, type ClusterVector, type ClusterInput, type ClusterAssignment, type ClusterResult, type ClusterPolicy, type ContextProfile, } from './cluster/index.js';
|
|
58
59
|
//# sourceMappingURL=index.d.ts.map
|