circle-ir-ai 2.22.0 → 2.27.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 +390 -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/backend.d.ts +52 -0
- package/dist/cache/backend.d.ts.map +1 -0
- package/dist/cache/backend.js +19 -0
- package/dist/cache/backend.js.map +1 -0
- package/dist/cache/backends/index.d.ts +32 -0
- package/dist/cache/backends/index.d.ts.map +1 -0
- package/dist/cache/backends/index.js +76 -0
- package/dist/cache/backends/index.js.map +1 -0
- package/dist/cache/backends/local-fs.d.ts +31 -0
- package/dist/cache/backends/local-fs.d.ts.map +1 -0
- package/dist/cache/backends/local-fs.js +101 -0
- package/dist/cache/backends/local-fs.js.map +1 -0
- package/dist/cache/backends/memory.d.ts +19 -0
- package/dist/cache/backends/memory.d.ts.map +1 -0
- package/dist/cache/backends/memory.js +30 -0
- package/dist/cache/backends/memory.js.map +1 -0
- package/dist/cache/backends/r2.d.ts +51 -0
- package/dist/cache/backends/r2.d.ts.map +1 -0
- package/dist/cache/backends/r2.js +116 -0
- package/dist/cache/backends/r2.js.map +1 -0
- package/dist/cache/classification-cache.d.ts +23 -9
- package/dist/cache/classification-cache.d.ts.map +1 -1
- package/dist/cache/classification-cache.js +37 -64
- package/dist/cache/classification-cache.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/index.d.ts +4 -0
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +2 -0
- package/dist/cache/index.js.map +1 -1
- 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/batch-classifier.js +2 -2
- package/dist/llm/batch-classifier.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 +37 -0
- package/dist/llm/verification.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tree Cache
|
|
3
|
+
*
|
|
4
|
+
* Persistent on-disk cache for `runPatternMatch` output (cognium-ai#153,
|
|
5
|
+
* P3 of epic #155). Pattern-match output is a pure function of file
|
|
6
|
+
* content + engine version, so caching it eliminates the parse +
|
|
7
|
+
* AST-walk + SAST-rule firing on warm runs.
|
|
8
|
+
*
|
|
9
|
+
* Empirically (v2.20.6 gson re-verify, 2026-06-29) the scan stage ate
|
|
10
|
+
* 179s of 358s end-to-end — ~half the wall-clock is re-discovering
|
|
11
|
+
* structure circle-ir already knows. Caching the pattern-match seam
|
|
12
|
+
* is the smallest empirical win in the cache stack (no LLM-token
|
|
13
|
+
* reduction, only CPU + wall-clock), but it stacks cleanly on the
|
|
14
|
+
* #145 static pre-filter — a cached tree means the pre-filter has
|
|
15
|
+
* more to chew on, which reduces enrichment calls downstream.
|
|
16
|
+
*
|
|
17
|
+
* **Scope:** caches `PatternMatchResult` only, NOT full `CircleIR`.
|
|
18
|
+
* The full graph (cross-file CFG, project-level type hierarchy) is
|
|
19
|
+
* too entangled with project context to cache safely without a full
|
|
20
|
+
* `CircleIR.serialize()` upstream — that's a separate D3 design
|
|
21
|
+
* question, file separately if pursued.
|
|
22
|
+
*
|
|
23
|
+
* **Key composition:**
|
|
24
|
+
* content = SHA-256(sourceCode) + '\0' +
|
|
25
|
+
* circleIrVersion + '\0' +
|
|
26
|
+
* circleIrAiVersion + '\0' +
|
|
27
|
+
* language + '\0' +
|
|
28
|
+
* ruleSetFingerprint
|
|
29
|
+
* classifier = 'tree-pattern-match'
|
|
30
|
+
*
|
|
31
|
+
* Any of: file edit, circle-ir bump, circle-ir-ai bump, language
|
|
32
|
+
* change, or rule-set change → cache miss.
|
|
33
|
+
*
|
|
34
|
+
* **Storage:** `ClassificationCache<PatternMatchResult>` under
|
|
35
|
+
* `.cognium/cache/tree/`, 7-day TTL (longer than discovery cache
|
|
36
|
+
* because the input is structural and stable — pattern-match output
|
|
37
|
+
* doesn't drift between scans the way an LLM call would).
|
|
38
|
+
*
|
|
39
|
+
* **Env toggles:**
|
|
40
|
+
* LLM_TREE_CACHE=0 → disable persistent tree cache.
|
|
41
|
+
*
|
|
42
|
+
* **Versioning note:** unlike discovery-cache / verify-cache, this
|
|
43
|
+
* cache is NOT keyed on the LLM model fingerprint (pattern-match is
|
|
44
|
+
* static — circle-ir doesn't call any LLM). It IS keyed on the
|
|
45
|
+
* circle-ir and circle-ir-ai package versions because either bump
|
|
46
|
+
* can change the workflow-level transforms applied to the result.
|
|
47
|
+
*/
|
|
48
|
+
import * as crypto from 'crypto';
|
|
49
|
+
import * as fs from 'fs';
|
|
50
|
+
import * as path from 'path';
|
|
51
|
+
import { createRequire } from 'module';
|
|
52
|
+
import { ClassificationCache } from './classification-cache.js';
|
|
53
|
+
const TREE_CACHE_SUBDIR = path.join('.cognium', 'cache', 'tree');
|
|
54
|
+
const TREE_CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days — structural, stable
|
|
55
|
+
/**
|
|
56
|
+
* Module-scoped singleton — distinct from the verify/discovery
|
|
57
|
+
* singletons so the tree cache (which doesn't depend on the LLM model)
|
|
58
|
+
* doesn't get invalidated when the operator swaps discovery model.
|
|
59
|
+
*/
|
|
60
|
+
let _instance = null;
|
|
61
|
+
/**
|
|
62
|
+
* Read package versions once at module load (best-effort). Wrapped in a
|
|
63
|
+
* try/catch so unit tests that don't ship a package.json next to the
|
|
64
|
+
* source can still construct the cache; in that case the version
|
|
65
|
+
* component degrades to 'unknown' and the cache still works (just isn't
|
|
66
|
+
* cross-version-safe).
|
|
67
|
+
*/
|
|
68
|
+
function safeReadVersion(spec, baseUrl) {
|
|
69
|
+
try {
|
|
70
|
+
const require = createRequire(baseUrl);
|
|
71
|
+
return require(spec).version || 'unknown';
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return 'unknown';
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const _circleIrVersion = safeReadVersion('circle-ir/package.json', import.meta.url);
|
|
78
|
+
const _circleIrAiVersion = (() => {
|
|
79
|
+
// The package's own version is harder to resolve via require, so read
|
|
80
|
+
// it directly from disk by walking up from this file.
|
|
81
|
+
try {
|
|
82
|
+
// Compiled output sits at dist/cache/tree-cache.js → ../../package.json
|
|
83
|
+
const candidates = [
|
|
84
|
+
path.resolve(new URL(import.meta.url).pathname, '../../../package.json'),
|
|
85
|
+
path.resolve(new URL(import.meta.url).pathname, '../../package.json'),
|
|
86
|
+
];
|
|
87
|
+
for (const p of candidates) {
|
|
88
|
+
if (fs.existsSync(p)) {
|
|
89
|
+
const pkg = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
90
|
+
if (pkg.name === 'circle-ir-ai' && pkg.version) {
|
|
91
|
+
return pkg.version;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
/* fallthrough */
|
|
98
|
+
}
|
|
99
|
+
return 'unknown';
|
|
100
|
+
})();
|
|
101
|
+
/**
|
|
102
|
+
* Get the tree-cache singleton. When `LLM_TREE_CACHE=0` returns a
|
|
103
|
+
* disabled cache that no-ops on get/set (callers don't need to branch).
|
|
104
|
+
*/
|
|
105
|
+
export function getTreeCache() {
|
|
106
|
+
const enabled = process.env.LLM_TREE_CACHE !== '0';
|
|
107
|
+
if (!_instance) {
|
|
108
|
+
_instance = new ClassificationCache({
|
|
109
|
+
cacheDir: path.join(process.cwd(), TREE_CACHE_SUBDIR),
|
|
110
|
+
maxAge: TREE_CACHE_TTL_MS,
|
|
111
|
+
enabled,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
return _instance;
|
|
115
|
+
}
|
|
116
|
+
/** Reset the module-scoped singleton — test-only. */
|
|
117
|
+
export function resetTreeCache() {
|
|
118
|
+
_instance = null;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Compute the `(content, classifier)` tuple for the underlying
|
|
122
|
+
* ClassificationCache.
|
|
123
|
+
*
|
|
124
|
+
* Components:
|
|
125
|
+
* - source code SHA-256 — file edit invalidates only that file's entry
|
|
126
|
+
* - circleIrVersion — bumping circle-ir invalidates all entries
|
|
127
|
+
* - circleIrAiVersion — bumping circle-ir-ai (which may change
|
|
128
|
+
* workflow-level transforms applied to pattern-match output)
|
|
129
|
+
* invalidates all entries
|
|
130
|
+
* - language — same source, different language tag must miss (the
|
|
131
|
+
* analyzer's behavior depends on the language argument)
|
|
132
|
+
* - ruleSetFingerprint — caller-supplied digest of the active rule
|
|
133
|
+
* set (disabledPasses + projectProfile). Empty string is fine for
|
|
134
|
+
* the default rule set.
|
|
135
|
+
*/
|
|
136
|
+
export function computeTreeCacheKey(input) {
|
|
137
|
+
const sourceSha = crypto.createHash('sha256').update(input.sourceCode).digest('hex');
|
|
138
|
+
const ruleSet = input.ruleSetFingerprint ?? '';
|
|
139
|
+
return {
|
|
140
|
+
content: `${sourceSha}\0${_circleIrVersion}\0${_circleIrAiVersion}\0${input.language}\0${ruleSet}`,
|
|
141
|
+
classifier: 'tree-pattern-match',
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Compute a stable fingerprint over an arbitrary rule-set descriptor
|
|
146
|
+
* (disabledPasses array + projectProfile object). Result is suitable to
|
|
147
|
+
* pass as `ruleSetFingerprint` to `computeTreeCacheKey`. Order-stable
|
|
148
|
+
* for arrays so re-ordering `--disable a,b` vs `--disable b,a` still
|
|
149
|
+
* hits the cache.
|
|
150
|
+
*/
|
|
151
|
+
export function computeRuleSetFingerprint(input) {
|
|
152
|
+
const passes = [...(input.disabledPasses ?? [])].sort().join(',');
|
|
153
|
+
// projectProfile JSON-stringifies; key order in objects matters only
|
|
154
|
+
// if the producer is non-deterministic — `@cognium/project-profile-detect`
|
|
155
|
+
// emits stable keys, so this is fine. If a future profile producer is
|
|
156
|
+
// less stable we can switch to a sorted-keys serializer.
|
|
157
|
+
const profile = input.projectProfile === undefined
|
|
158
|
+
? ''
|
|
159
|
+
: JSON.stringify(input.projectProfile);
|
|
160
|
+
if (!passes && !profile)
|
|
161
|
+
return '';
|
|
162
|
+
return crypto.createHash('sha256').update(`${passes}\0${profile}`).digest('hex');
|
|
163
|
+
}
|
|
164
|
+
/** Test-only: expose the captured engine versions for assertions. */
|
|
165
|
+
export function getTreeCacheVersions() {
|
|
166
|
+
return {
|
|
167
|
+
circleIrVersion: _circleIrVersion,
|
|
168
|
+
circleIrAiVersion: _circleIrAiVersion,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=tree-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-cache.js","sourceRoot":"","sources":["../../src/cache/tree-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verify Cache
|
|
3
|
+
*
|
|
4
|
+
* Persistent on-disk cache for LLM verification batch results
|
|
5
|
+
* (cognium-ai#152, P1 of epic #155). Sits in front of the in-memory
|
|
6
|
+
* `_verifierDedupCache` from verification.ts (#138 step 3) so that
|
|
7
|
+
* identical `(file SHA, pair-set)` requests survive across processes,
|
|
8
|
+
* CI runs, and developer iterations — not just within one process.
|
|
9
|
+
*
|
|
10
|
+
* Built on top of `ClassificationCache<BatchVerificationResult>` (which
|
|
11
|
+
* already carries the cognium-ai#151 model-fingerprint key dimension),
|
|
12
|
+
* with verify-specific key construction:
|
|
13
|
+
*
|
|
14
|
+
* content = SHA-256(code) + '\\0' + pairsFingerprint
|
|
15
|
+
* classifier = 'verify-batch'
|
|
16
|
+
* fingerprint = getPhaseModelFingerprint(config) // includes verify model
|
|
17
|
+
*
|
|
18
|
+
* Cache directory: `.cognium/cache/verify/` (separate from the
|
|
19
|
+
* discovery-phase `.cognium/cache/` so a `rm -rf .cognium/cache/verify/`
|
|
20
|
+
* only nukes verifier entries).
|
|
21
|
+
*
|
|
22
|
+
* Invalidation matrix (acceptance criteria #152):
|
|
23
|
+
* - Edit one file in a project → only that file's entries invalidate
|
|
24
|
+
* (file SHA-256 is part of the cache content key)
|
|
25
|
+
* - Add a new sink to the engine → existing entries still hit if the
|
|
26
|
+
* new sink doesn't change the pair-set for that file
|
|
27
|
+
* - Change verification model → entire cache invalidates
|
|
28
|
+
* (model fingerprint is part of the singleton key)
|
|
29
|
+
*
|
|
30
|
+
* Env toggles:
|
|
31
|
+
* LLM_VERIFY_CACHE=0 → disable persistent verify cache (in-memory
|
|
32
|
+
* dedup from #138 still applies)
|
|
33
|
+
*/
|
|
34
|
+
import { ClassificationCache } from './classification-cache.js';
|
|
35
|
+
import { type LLMConfig } from '../llm/config.js';
|
|
36
|
+
import type { BatchVerificationInput, BatchVerificationResult } from '../llm/verification.js';
|
|
37
|
+
/**
|
|
38
|
+
* Get the verify-phase persistent cache, keyed by per-phase model
|
|
39
|
+
* fingerprint. When `LLM_VERIFY_CACHE=0` returns a disabled cache that
|
|
40
|
+
* no-ops on get/set (callers don't need to branch).
|
|
41
|
+
*/
|
|
42
|
+
export declare function getVerifyCache(config?: LLMConfig): ClassificationCache<BatchVerificationResult>;
|
|
43
|
+
/** Reset the module-scoped singleton — test-only. */
|
|
44
|
+
export declare function resetVerifyCache(): void;
|
|
45
|
+
/**
|
|
46
|
+
* Compute the `(content, classifier)` tuple for the underlying
|
|
47
|
+
* ClassificationCache. The fingerprint dimension is folded in by the
|
|
48
|
+
* cache itself (see classification-cache.ts:computeKey).
|
|
49
|
+
*
|
|
50
|
+
* Components:
|
|
51
|
+
* - file SHA-256 — file edit invalidates only that file's entry
|
|
52
|
+
* - pairs fingerprint — sort-invariant over the source/sink set
|
|
53
|
+
* - classifier 'verify-batch' — namespace for future
|
|
54
|
+
* 'verify-pair' / 'verify-flow' tiers without collision
|
|
55
|
+
*/
|
|
56
|
+
export declare function computeVerifyCacheKey(input: BatchVerificationInput): {
|
|
57
|
+
content: string;
|
|
58
|
+
classifier: string;
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=verify-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-cache.d.ts","sourceRoot":"","sources":["../../src/cache/verify-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAIH,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAiD,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,KAAK,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAa9F;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,GAAE,SAAiC,GACxC,mBAAmB,CAAC,uBAAuB,CAAC,CAc9C;AAED,qDAAqD;AACrD,wBAAgB,gBAAgB,IAAI,IAAI,CAGvC;AAiBD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,sBAAsB,GAC5B;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAOzC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verify Cache
|
|
3
|
+
*
|
|
4
|
+
* Persistent on-disk cache for LLM verification batch results
|
|
5
|
+
* (cognium-ai#152, P1 of epic #155). Sits in front of the in-memory
|
|
6
|
+
* `_verifierDedupCache` from verification.ts (#138 step 3) so that
|
|
7
|
+
* identical `(file SHA, pair-set)` requests survive across processes,
|
|
8
|
+
* CI runs, and developer iterations — not just within one process.
|
|
9
|
+
*
|
|
10
|
+
* Built on top of `ClassificationCache<BatchVerificationResult>` (which
|
|
11
|
+
* already carries the cognium-ai#151 model-fingerprint key dimension),
|
|
12
|
+
* with verify-specific key construction:
|
|
13
|
+
*
|
|
14
|
+
* content = SHA-256(code) + '\\0' + pairsFingerprint
|
|
15
|
+
* classifier = 'verify-batch'
|
|
16
|
+
* fingerprint = getPhaseModelFingerprint(config) // includes verify model
|
|
17
|
+
*
|
|
18
|
+
* Cache directory: `.cognium/cache/verify/` (separate from the
|
|
19
|
+
* discovery-phase `.cognium/cache/` so a `rm -rf .cognium/cache/verify/`
|
|
20
|
+
* only nukes verifier entries).
|
|
21
|
+
*
|
|
22
|
+
* Invalidation matrix (acceptance criteria #152):
|
|
23
|
+
* - Edit one file in a project → only that file's entries invalidate
|
|
24
|
+
* (file SHA-256 is part of the cache content key)
|
|
25
|
+
* - Add a new sink to the engine → existing entries still hit if the
|
|
26
|
+
* new sink doesn't change the pair-set for that file
|
|
27
|
+
* - Change verification model → entire cache invalidates
|
|
28
|
+
* (model fingerprint is part of the singleton key)
|
|
29
|
+
*
|
|
30
|
+
* Env toggles:
|
|
31
|
+
* LLM_VERIFY_CACHE=0 → disable persistent verify cache (in-memory
|
|
32
|
+
* dedup from #138 still applies)
|
|
33
|
+
*/
|
|
34
|
+
import * as crypto from 'crypto';
|
|
35
|
+
import * as path from 'path';
|
|
36
|
+
import { ClassificationCache } from './classification-cache.js';
|
|
37
|
+
import { getDefaultLLMConfig, getPhaseModelFingerprint } from '../llm/config.js';
|
|
38
|
+
const VERIFY_CACHE_SUBDIR = path.join('.cognium', 'cache', 'verify');
|
|
39
|
+
/**
|
|
40
|
+
* Module-scoped singleton — distinct from the discovery-phase singleton
|
|
41
|
+
* in `classification-cache.ts` so the two phases can carry different
|
|
42
|
+
* model fingerprints (e.g. cheap discovery + strong verifier) without
|
|
43
|
+
* thrashing each other's cache instance.
|
|
44
|
+
*/
|
|
45
|
+
let _instance = null;
|
|
46
|
+
let _instanceFingerprint = '';
|
|
47
|
+
/**
|
|
48
|
+
* Get the verify-phase persistent cache, keyed by per-phase model
|
|
49
|
+
* fingerprint. When `LLM_VERIFY_CACHE=0` returns a disabled cache that
|
|
50
|
+
* no-ops on get/set (callers don't need to branch).
|
|
51
|
+
*/
|
|
52
|
+
export function getVerifyCache(config = getDefaultLLMConfig()) {
|
|
53
|
+
const enabled = process.env.LLM_VERIFY_CACHE !== '0';
|
|
54
|
+
const fingerprint = getPhaseModelFingerprint(config);
|
|
55
|
+
if (!_instance || _instanceFingerprint !== fingerprint || _instance.getModelFingerprint() !== fingerprint) {
|
|
56
|
+
_instance = new ClassificationCache({
|
|
57
|
+
cacheDir: path.join(process.cwd(), VERIFY_CACHE_SUBDIR),
|
|
58
|
+
modelFingerprint: fingerprint,
|
|
59
|
+
enabled,
|
|
60
|
+
});
|
|
61
|
+
_instanceFingerprint = fingerprint;
|
|
62
|
+
}
|
|
63
|
+
return _instance;
|
|
64
|
+
}
|
|
65
|
+
/** Reset the module-scoped singleton — test-only. */
|
|
66
|
+
export function resetVerifyCache() {
|
|
67
|
+
_instance = null;
|
|
68
|
+
_instanceFingerprint = '';
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Stable sort over the source/sink pair-set; never mutates the caller's
|
|
72
|
+
* arrays. Mirrors `_serializeVerifierPairs` in verification.ts so
|
|
73
|
+
* persistent + in-memory dedup agree on what counts as "the same call".
|
|
74
|
+
*/
|
|
75
|
+
function serializeVerifyPairs(input) {
|
|
76
|
+
const sources = [...input.sources]
|
|
77
|
+
.map((s) => `${s.line}|${s.type}|${s.variable ?? ''}`)
|
|
78
|
+
.sort();
|
|
79
|
+
const sinks = [...input.sinks]
|
|
80
|
+
.map((s) => `${s.line}|${s.type}|${s.cwe}|${s.method ?? ''}`)
|
|
81
|
+
.sort();
|
|
82
|
+
return JSON.stringify({ sources, sinks });
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Compute the `(content, classifier)` tuple for the underlying
|
|
86
|
+
* ClassificationCache. The fingerprint dimension is folded in by the
|
|
87
|
+
* cache itself (see classification-cache.ts:computeKey).
|
|
88
|
+
*
|
|
89
|
+
* Components:
|
|
90
|
+
* - file SHA-256 — file edit invalidates only that file's entry
|
|
91
|
+
* - pairs fingerprint — sort-invariant over the source/sink set
|
|
92
|
+
* - classifier 'verify-batch' — namespace for future
|
|
93
|
+
* 'verify-pair' / 'verify-flow' tiers without collision
|
|
94
|
+
*/
|
|
95
|
+
export function computeVerifyCacheKey(input) {
|
|
96
|
+
const fileSha = crypto.createHash('sha256').update(input.code).digest('hex');
|
|
97
|
+
const pairsFp = crypto.createHash('sha256').update(serializeVerifyPairs(input)).digest('hex');
|
|
98
|
+
return {
|
|
99
|
+
content: `${fileSha}\0${pairsFp}`,
|
|
100
|
+
classifier: 'verify-batch',
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=verify-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-cache.js","sourceRoot":"","sources":["../../src/cache/verify-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAkB,MAAM,kBAAkB,CAAC;AAGjG,MAAM,mBAAmB,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AAErE;;;;;GAKG;AACH,IAAI,SAAS,GAAwD,IAAI,CAAC;AAC1E,IAAI,oBAAoB,GAAG,EAAE,CAAC;AAE9B;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,SAAoB,mBAAmB,EAAE;IAEzC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,GAAG,CAAC;IACrD,MAAM,WAAW,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAC;IAErD,IAAI,CAAC,SAAS,IAAI,oBAAoB,KAAK,WAAW,IAAI,SAAS,CAAC,mBAAmB,EAAE,KAAK,WAAW,EAAE,CAAC;QAC1G,SAAS,GAAG,IAAI,mBAAmB,CAA0B;YAC3D,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,mBAAmB,CAAC;YACvD,gBAAgB,EAAE,WAAW;YAC7B,OAAO;SACR,CAAC,CAAC;QACH,oBAAoB,GAAG,WAAW,CAAC;IACrC,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,gBAAgB;IAC9B,SAAS,GAAG,IAAI,CAAC;IACjB,oBAAoB,GAAG,EAAE,CAAC;AAC5B,CAAC;AAED;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,KAA6B;IACzD,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC;SAC/B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;SACrD,IAAI,EAAE,CAAC;IACV,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;SAC3B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;SAC5D,IAAI,EAAE,CAAC;IACV,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAA6B;IAE7B,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7E,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9F,OAAO;QACL,OAAO,EAAE,GAAG,OAAO,KAAK,OAAO,EAAE;QACjC,UAAU,EAAE,cAAc;KAC3B,CAAC;AACJ,CAAC"}
|
|
@@ -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"}
|