circle-ir-ai 2.26.0 → 2.28.1

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.
Files changed (71) hide show
  1. package/CHANGELOG.md +205 -0
  2. package/dist/agents/mastra/workflow.d.ts +15 -0
  3. package/dist/agents/mastra/workflow.d.ts.map +1 -1
  4. package/dist/agents/mastra/workflow.js +33 -12
  5. package/dist/agents/mastra/workflow.js.map +1 -1
  6. package/dist/cache/backend.d.ts +104 -0
  7. package/dist/cache/backend.d.ts.map +1 -0
  8. package/dist/cache/backend.js +35 -0
  9. package/dist/cache/backend.js.map +1 -0
  10. package/dist/cache/backends/index.d.ts +44 -0
  11. package/dist/cache/backends/index.d.ts.map +1 -0
  12. package/dist/cache/backends/index.js +84 -0
  13. package/dist/cache/backends/index.js.map +1 -0
  14. package/dist/cache/backends/layout.d.ts +31 -0
  15. package/dist/cache/backends/layout.d.ts.map +1 -0
  16. package/dist/cache/backends/layout.js +46 -0
  17. package/dist/cache/backends/layout.js.map +1 -0
  18. package/dist/cache/backends/local-fs.d.ts +34 -0
  19. package/dist/cache/backends/local-fs.d.ts.map +1 -0
  20. package/dist/cache/backends/local-fs.js +113 -0
  21. package/dist/cache/backends/local-fs.js.map +1 -0
  22. package/dist/cache/backends/memory.d.ts +24 -0
  23. package/dist/cache/backends/memory.d.ts.map +1 -0
  24. package/dist/cache/backends/memory.js +38 -0
  25. package/dist/cache/backends/memory.js.map +1 -0
  26. package/dist/cache/backends/r2.d.ts +51 -0
  27. package/dist/cache/backends/r2.d.ts.map +1 -0
  28. package/dist/cache/backends/r2.js +114 -0
  29. package/dist/cache/backends/r2.js.map +1 -0
  30. package/dist/cache/classification-cache.d.ts +90 -34
  31. package/dist/cache/classification-cache.d.ts.map +1 -1
  32. package/dist/cache/classification-cache.js +131 -106
  33. package/dist/cache/classification-cache.js.map +1 -1
  34. package/dist/cache/coordinate.d.ts +59 -0
  35. package/dist/cache/coordinate.d.ts.map +1 -0
  36. package/dist/cache/coordinate.js +240 -0
  37. package/dist/cache/coordinate.js.map +1 -0
  38. package/dist/cache/discovery-cache.d.ts +40 -36
  39. package/dist/cache/discovery-cache.d.ts.map +1 -1
  40. package/dist/cache/discovery-cache.js +50 -42
  41. package/dist/cache/discovery-cache.js.map +1 -1
  42. package/dist/cache/index.d.ts +4 -0
  43. package/dist/cache/index.d.ts.map +1 -1
  44. package/dist/cache/index.js +2 -0
  45. package/dist/cache/index.js.map +1 -1
  46. package/dist/cache/tree-cache.d.ts +48 -53
  47. package/dist/cache/tree-cache.d.ts.map +1 -1
  48. package/dist/cache/tree-cache.js +87 -72
  49. package/dist/cache/tree-cache.js.map +1 -1
  50. package/dist/cache/verify-cache.d.ts +26 -21
  51. package/dist/cache/verify-cache.d.ts.map +1 -1
  52. package/dist/cache/verify-cache.js +37 -29
  53. package/dist/cache/verify-cache.js.map +1 -1
  54. package/dist/llm/batch-classifier.d.ts.map +1 -1
  55. package/dist/llm/batch-classifier.js +3 -2
  56. package/dist/llm/batch-classifier.js.map +1 -1
  57. package/dist/llm/config.d.ts +34 -8
  58. package/dist/llm/config.d.ts.map +1 -1
  59. package/dist/llm/config.js +52 -12
  60. package/dist/llm/config.js.map +1 -1
  61. package/dist/llm/discovery.d.ts.map +1 -1
  62. package/dist/llm/discovery.js +52 -6
  63. package/dist/llm/discovery.js.map +1 -1
  64. package/dist/llm/verification.d.ts.map +1 -1
  65. package/dist/llm/verification.js +51 -9
  66. package/dist/llm/verification.js.map +1 -1
  67. package/dist/security-scan/scanner.d.ts +15 -0
  68. package/dist/security-scan/scanner.d.ts.map +1 -1
  69. package/dist/security-scan/scanner.js +34 -0
  70. package/dist/security-scan/scanner.js.map +1 -1
  71. package/package.json +3 -2
@@ -0,0 +1,240 @@
1
+ /**
2
+ * Package coordinate detection for cache path layout.
3
+ *
4
+ * The tree-cache backend (R2 / local-fs) uses the coordinate to build a
5
+ * package-aware key layout:
6
+ *
7
+ * tree/<ecosystem>/<name>@<version>/<4hex>/<sha>.json (published coords)
8
+ * tree/_local/<name>@<version>/<4hex>/<sha>.json (repo-root manifest)
9
+ * tree/_unowned/<4hex>/<sha>.json (no coordinate)
10
+ *
11
+ * Coordinate is resolved ONCE per scan from the repo root. We deliberately
12
+ * keep the extractor minimal (only manifest files we can parse with zero
13
+ * deps) so it can be folded into hot paths without measurable overhead.
14
+ *
15
+ * What's intentionally *not* in scope here:
16
+ * - per-file coordinate from `node_modules/<pkg>/...` paths (deferred until
17
+ * we actually scan transitive deps)
18
+ * - lockfile-derived coordinates
19
+ * - Maven `<artifactId>` resolution from a multi-module reactor
20
+ *
21
+ * For the first-party github sweep use case, every file in a repo shares
22
+ * the same coordinate (or falls through to `_unowned`), which is exactly
23
+ * what we want for cross-runner cache sharing.
24
+ */
25
+ import * as fs from 'fs';
26
+ import * as path from 'path';
27
+ /**
28
+ * The sentinel coordinate emitted when the repo has no detectable manifest.
29
+ *
30
+ * Tree-cache content still gets cached, just under `_unowned/<4hex>/<sha>`.
31
+ * Re-using the singleton means the path layout is constant for un-coord'd
32
+ * scans and avoids per-file object allocation.
33
+ */
34
+ export const UNOWNED = Object.freeze({
35
+ ecosystem: '_unowned',
36
+ name: '_',
37
+ version: '_',
38
+ });
39
+ /**
40
+ * Render the coordinate as a stable path prefix and a stable hash prefix.
41
+ *
42
+ * `pathSegment` is what the backend uses to build the R2 / local-fs key.
43
+ * `hashPrefix` is what cache-key composers fold into the content hash so
44
+ * the SHA itself encodes the coordinate (no collision across packages).
45
+ */
46
+ export function coordinateSegments(c) {
47
+ if (c.ecosystem === '_unowned') {
48
+ return { pathSegment: '_unowned', hashPrefix: '' };
49
+ }
50
+ const slug = `${c.name}@${c.version}`;
51
+ return {
52
+ pathSegment: `${c.ecosystem}/${slug}`,
53
+ hashPrefix: `${c.ecosystem}\0${slug}`,
54
+ };
55
+ }
56
+ /**
57
+ * Detect a package coordinate from the repo root manifest files.
58
+ *
59
+ * Synchronous because it runs once per scan at scanner entry and the
60
+ * disk reads are tiny (`package.json` / `pom.xml`).
61
+ */
62
+ export function detectCoordinate(repoRoot) {
63
+ // npm — package.json
64
+ const pkgJsonPath = path.join(repoRoot, 'package.json');
65
+ if (fs.existsSync(pkgJsonPath)) {
66
+ try {
67
+ const raw = fs.readFileSync(pkgJsonPath, 'utf8');
68
+ const json = JSON.parse(raw);
69
+ const name = typeof json.name === 'string' ? json.name.trim() : '';
70
+ const version = typeof json.version === 'string' ? json.version.trim() : '';
71
+ if (name && version) {
72
+ // `private: true` packages are by definition not published — use
73
+ // `_local` so the layout still groups them but doesn't pollute
74
+ // an ecosystem namespace with unpublishable coords.
75
+ const isPrivate = json.private === true;
76
+ return {
77
+ ecosystem: isPrivate ? '_local' : 'npm',
78
+ name: name.toLowerCase(),
79
+ version,
80
+ };
81
+ }
82
+ if (name) {
83
+ return { ecosystem: '_local', name: name.toLowerCase(), version: 'HEAD' };
84
+ }
85
+ }
86
+ catch {
87
+ // fallthrough
88
+ }
89
+ }
90
+ // maven — pom.xml (regex-only; no XML parser dep)
91
+ const pomPath = path.join(repoRoot, 'pom.xml');
92
+ if (fs.existsSync(pomPath)) {
93
+ try {
94
+ const raw = fs.readFileSync(pomPath, 'utf8');
95
+ const coord = parsePomCoordinate(raw);
96
+ if (coord)
97
+ return coord;
98
+ }
99
+ catch {
100
+ // fallthrough
101
+ }
102
+ }
103
+ // pyproject.toml — minimal `[project] name = "...", version = "..."` lift
104
+ const pyprojectPath = path.join(repoRoot, 'pyproject.toml');
105
+ if (fs.existsSync(pyprojectPath)) {
106
+ try {
107
+ const raw = fs.readFileSync(pyprojectPath, 'utf8');
108
+ const coord = parsePyprojectCoordinate(raw);
109
+ if (coord)
110
+ return coord;
111
+ }
112
+ catch {
113
+ // fallthrough
114
+ }
115
+ }
116
+ // Cargo.toml — `[package] name = "...", version = "..."`
117
+ const cargoPath = path.join(repoRoot, 'Cargo.toml');
118
+ if (fs.existsSync(cargoPath)) {
119
+ try {
120
+ const raw = fs.readFileSync(cargoPath, 'utf8');
121
+ const coord = parseCargoCoordinate(raw);
122
+ if (coord)
123
+ return coord;
124
+ }
125
+ catch {
126
+ // fallthrough
127
+ }
128
+ }
129
+ // go.mod — `module <path>` (no version in manifest; use HEAD)
130
+ const goModPath = path.join(repoRoot, 'go.mod');
131
+ if (fs.existsSync(goModPath)) {
132
+ try {
133
+ const raw = fs.readFileSync(goModPath, 'utf8');
134
+ const match = /^module\s+(\S+)\s*$/m.exec(raw);
135
+ if (match?.[1]) {
136
+ return { ecosystem: 'go', name: match[1].toLowerCase(), version: 'HEAD' };
137
+ }
138
+ }
139
+ catch {
140
+ // fallthrough
141
+ }
142
+ }
143
+ // Fallback: use repo-root basename as a `_local/<dir>@HEAD` coordinate so
144
+ // re-scans of the same on-disk repo still share cache, even without a
145
+ // manifest. The 4-hex shard under `_unowned` is reserved for truly
146
+ // anonymous content (e.g. ad-hoc file inputs from CI).
147
+ const basename = path.basename(path.resolve(repoRoot));
148
+ if (basename && basename !== '/' && basename !== '.') {
149
+ return { ecosystem: '_local', name: basename.toLowerCase(), version: 'HEAD' };
150
+ }
151
+ return UNOWNED;
152
+ }
153
+ /**
154
+ * Parse `<groupId>:<artifactId>:<version>` from the *top-level* of a pom.
155
+ *
156
+ * We intentionally read the project's own `<groupId>/<artifactId>/<version>`
157
+ * and fall through to `<parent>` only when the child block omits them
158
+ * (standard Maven inheritance). Sub-modules are not recursed; the cache
159
+ * shares the parent coordinate which is fine for cross-runner sharing.
160
+ */
161
+ function parsePomCoordinate(xml) {
162
+ // Strip XML comments to avoid commented-out parent blocks shadowing real ones.
163
+ const cleaned = xml.replace(/<!--[\s\S]*?-->/g, '');
164
+ // Find the top-level <project> children only — i.e. tags that appear
165
+ // before any sub-element opens. Cheap approximation: take the first
166
+ // occurrence of each tag at depth-1 by finding the first match.
167
+ const projectMatch = /<project\b[^>]*>([\s\S]*?)<\/project>/.exec(cleaned);
168
+ if (!projectMatch)
169
+ return null;
170
+ const body = projectMatch[1];
171
+ const direct = readDirectChildren(body);
172
+ let groupId = direct.groupId;
173
+ let artifactId = direct.artifactId;
174
+ let version = direct.version;
175
+ if (!groupId || !version) {
176
+ const parentMatch = /<parent\b[^>]*>([\s\S]*?)<\/parent>/.exec(body);
177
+ if (parentMatch) {
178
+ const parent = readDirectChildren(parentMatch[1]);
179
+ groupId ??= parent.groupId;
180
+ version ??= parent.version;
181
+ }
182
+ }
183
+ if (!groupId || !artifactId || !version)
184
+ return null;
185
+ return {
186
+ ecosystem: 'maven',
187
+ name: `${groupId.toLowerCase()}:${artifactId.toLowerCase()}`,
188
+ version,
189
+ };
190
+ }
191
+ function readDirectChildren(body) {
192
+ const pick = (tag) => {
193
+ const re = new RegExp(`<${tag}>\\s*([^<\\s][^<]*?)\\s*</${tag}>`);
194
+ const m = re.exec(body);
195
+ return m?.[1]?.trim();
196
+ };
197
+ return {
198
+ groupId: pick('groupId'),
199
+ artifactId: pick('artifactId'),
200
+ version: pick('version'),
201
+ };
202
+ }
203
+ function parsePyprojectCoordinate(toml) {
204
+ // Look for `[project]` table, then `name = "..."` and `version = "..."`
205
+ // inside it. Handle `[tool.poetry]` as a fallback for legacy Poetry
206
+ // layouts.
207
+ const tryTable = (header) => {
208
+ const re = new RegExp(`\\[${header}\\]([\\s\\S]*?)(?=\\n\\[|$)`, 'm');
209
+ const m = re.exec(toml);
210
+ if (!m)
211
+ return null;
212
+ const body = m[1];
213
+ const nameMatch = /^\s*name\s*=\s*['"]([^'"]+)['"]/m.exec(body);
214
+ const versionMatch = /^\s*version\s*=\s*['"]([^'"]+)['"]/m.exec(body);
215
+ if (!nameMatch || !versionMatch)
216
+ return null;
217
+ return {
218
+ ecosystem: 'pypi',
219
+ name: nameMatch[1].toLowerCase(),
220
+ version: versionMatch[1],
221
+ };
222
+ };
223
+ return tryTable('project') ?? tryTable('tool\\.poetry');
224
+ }
225
+ function parseCargoCoordinate(toml) {
226
+ const m = /\[package\]([\s\S]*?)(?=\n\[|$)/m.exec(toml);
227
+ if (!m)
228
+ return null;
229
+ const body = m[1];
230
+ const nameMatch = /^\s*name\s*=\s*['"]([^'"]+)['"]/m.exec(body);
231
+ const versionMatch = /^\s*version\s*=\s*['"]([^'"]+)['"]/m.exec(body);
232
+ if (!nameMatch || !versionMatch)
233
+ return null;
234
+ return {
235
+ ecosystem: 'cargo',
236
+ name: nameMatch[1].toLowerCase(),
237
+ version: versionMatch[1],
238
+ };
239
+ }
240
+ //# sourceMappingURL=coordinate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinate.js","sourceRoot":"","sources":["../../src/cache/coordinate.ts"],"names":[],"mappings":"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"}
@@ -1,46 +1,48 @@
1
1
  /**
2
2
  * Discovery Cache
3
3
  *
4
- * Persistent on-disk cache for LLM discovery results per (className,
5
- * methodName, methodCode, CWE-set) tuple (cognium-ai#134, P2 of epic
6
- * #155). Sits in front of the in-memory `_discoveryDedupCache` from
7
- * discovery.ts (#136) so that identical method-level discovery requests
8
- * survive across processes, CI runs, and developer iterations — not just
9
- * within one process.
4
+ * Persistent on-disk cache for LLM discovery results per method
5
+ * (cognium-ai#134, P2 of epic #155, key reshape #158 Round 2).
10
6
  *
11
- * Built on top of `ClassificationCache<DiscoveryResult>` (which already
12
- * carries the cognium-ai#151 model-fingerprint key dimension), with
13
- * discovery-specific key construction:
7
+ * Sits in front of the in-memory `_discoveryDedupCache` from
8
+ * discovery.ts (#136) so identical method-level discovery requests
9
+ * survive across processes, CI runs, and developer iterations.
14
10
  *
15
- * content = className + '\\0' + methodName + '\\0' +
16
- * SHA-256(methodCode) + '\\0' + sortedCweSet
11
+ * **Key composition (Round 2 2.28.0):**
12
+ *
13
+ * content = methodSha + '\0' + sortedCweSet + '\0' + language
14
+ * + '\0' + PROMPT_VER
17
15
  * classifier = 'discovery-method'
18
- * fingerprint = getPhaseModelFingerprint(config) // includes discovery model
16
+ * fingerprint = getDiscoveryModelFingerprint() // discovery model ONLY
17
+ *
18
+ * **D6 fix:** dropped `className` and `methodName` from the key. They
19
+ * were redundant — if two different method *bodies* hash to the same
20
+ * SHA-256, they are byte-identical and the LLM's answer would be too.
21
+ * Including names also broke cache sharing on refactors that renamed
22
+ * a method without changing its body. (Names are still passed to the
23
+ * LLM as context inside the prompt; we just don't key the cache on
24
+ * them.)
19
25
  *
20
- * Cache directory: `.cognium/cache/discovery/` (separate from the
21
- * verify-phase `.cognium/cache/verify/` so each phase can be cleared
22
- * independently `rm -rf .cognium/cache/discovery/` only nukes
23
- * discovery entries).
26
+ * **D6 also adds `language`:** the same byte-identical snippet means
27
+ * very different things in Java vs Kotlin vs Scala — without language
28
+ * in the key, a Java result could be reused for a Kotlin call. Likely
29
+ * benign in practice but a correctness gap worth closing.
24
30
  *
25
- * Invalidation matrix (#134 acceptance criteria):
26
- * - Edit one method → only that method's entry invalidates
27
- * (methodCode SHA-256 is part of the key)
28
- * - Add a new CWE → existing entries still hit for old CWE-sets;
29
- * new CWE-set requests miss
30
- * - Change disc model → entire cache invalidates
31
- * (fingerprint is part of the singleton key)
31
+ * **D2 fix:** uses the discovery-only model fingerprint instead of the
32
+ * joint disc+verify+component fingerprint, so swapping the verify
33
+ * model doesn't invalidate discovery results.
34
+ *
35
+ * Cache namespace: `discovery` (separate from `tree` and `verify`).
32
36
  *
33
37
  * Env toggles:
34
- * LLM_DISCOVERY_CACHE=0 → disable persistent discovery cache
35
- * (in-memory dedup from #136 still applies)
38
+ * LLM_DISCOVERY_CACHE=0 → disable persistent discovery cache.
36
39
  */
37
40
  import { ClassificationCache } from './classification-cache.js';
38
41
  import { type LLMConfig } from '../llm/config.js';
39
42
  import type { DiscoveryResult } from '../llm/discovery.js';
40
43
  /**
41
44
  * Get the discovery-phase persistent cache, keyed by per-phase model
42
- * fingerprint. When `LLM_DISCOVERY_CACHE=0` returns a disabled cache that
43
- * no-ops on get/set (callers don't need to branch).
45
+ * fingerprint. When `LLM_DISCOVERY_CACHE=0` returns a disabled cache.
44
46
  */
45
47
  export declare function getDiscoveryCache(config?: LLMConfig): ClassificationCache<DiscoveryResult>;
46
48
  /** Reset the module-scoped singleton — test-only. */
@@ -48,24 +50,26 @@ export declare function resetDiscoveryCache(): void;
48
50
  /**
49
51
  * Compute the `(content, classifier)` tuple for the underlying
50
52
  * ClassificationCache. The fingerprint dimension is folded in by the
51
- * cache itself (see classification-cache.ts:computeKey).
53
+ * cache itself.
52
54
  *
53
55
  * Components:
54
- * - classNamedisambiguates same-named methods across classes
55
- * - methodName — per-method granularity (matches the per-method LLM call)
56
- * - methodCode SHA-256 — method edit invalidates only that method's entry
56
+ * - methodCode SHA-256 method edit invalidates only that entry
57
57
  * - sortedCweSet — different CWE-set requests on the same method don't
58
- * reuse each other's prompts (different system prompt, different answer)
59
- * - classifier 'discovery-method' namespace for future
60
- * 'discovery-file' / 'discovery-class' tiers without collision
58
+ * reuse each other's prompts
59
+ * - languageJava vs Kotlin etc. (D6 fix)
60
+ * - PROMPT_VER — global discovery-prompt invalidator
61
+ *
62
+ * Note: `className` / `methodName` are intentionally NOT in the key
63
+ * (D6 fix). They're prompt-context, not identity.
61
64
  */
62
65
  export declare function computeDiscoveryCacheKey(input: {
63
- className: string;
64
- methodName: string;
65
66
  methodCode: string;
66
67
  targetCWEs: ReadonlyArray<string>;
68
+ language: string;
67
69
  }): {
68
70
  content: string;
69
71
  classifier: string;
70
72
  };
73
+ /** Test-only: expose the prompt-version sentinel. */
74
+ export declare function getDiscoveryCachePromptVersion(): string;
71
75
  //# sourceMappingURL=discovery-cache.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"discovery-cache.d.ts","sourceRoot":"","sources":["../../src/cache/discovery-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAIH,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAiD,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAa3D;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,GAAE,SAAiC,GACxC,mBAAmB,CAAC,eAAe,CAAC,CActC;AAED,qDAAqD;AACrD,wBAAgB,mBAAmB,IAAI,IAAI,CAG1C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACnC,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAO1C"}
1
+ {"version":3,"file":"discovery-cache.d.ts","sourceRoot":"","sources":["../../src/cache/discovery-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAIH,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAc3D;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,GAAE,SAAiC,GACxC,mBAAmB,CAAC,eAAe,CAAC,CAetC;AAED,qDAAqD;AACrD,wBAAgB,mBAAmB,IAAI,IAAI,CAG1C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAO1C;AAED,qDAAqD;AACrD,wBAAgB,8BAA8B,IAAI,MAAM,CAEvD"}
@@ -1,62 +1,65 @@
1
1
  /**
2
2
  * Discovery Cache
3
3
  *
4
- * Persistent on-disk cache for LLM discovery results per (className,
5
- * methodName, methodCode, CWE-set) tuple (cognium-ai#134, P2 of epic
6
- * #155). Sits in front of the in-memory `_discoveryDedupCache` from
7
- * discovery.ts (#136) so that identical method-level discovery requests
8
- * survive across processes, CI runs, and developer iterations — not just
9
- * within one process.
4
+ * Persistent on-disk cache for LLM discovery results per method
5
+ * (cognium-ai#134, P2 of epic #155, key reshape #158 Round 2).
10
6
  *
11
- * Built on top of `ClassificationCache<DiscoveryResult>` (which already
12
- * carries the cognium-ai#151 model-fingerprint key dimension), with
13
- * discovery-specific key construction:
7
+ * Sits in front of the in-memory `_discoveryDedupCache` from
8
+ * discovery.ts (#136) so identical method-level discovery requests
9
+ * survive across processes, CI runs, and developer iterations.
14
10
  *
15
- * content = className + '\\0' + methodName + '\\0' +
16
- * SHA-256(methodCode) + '\\0' + sortedCweSet
11
+ * **Key composition (Round 2 2.28.0):**
12
+ *
13
+ * content = methodSha + '\0' + sortedCweSet + '\0' + language
14
+ * + '\0' + PROMPT_VER
17
15
  * classifier = 'discovery-method'
18
- * fingerprint = getPhaseModelFingerprint(config) // includes discovery model
16
+ * fingerprint = getDiscoveryModelFingerprint() // discovery model ONLY
17
+ *
18
+ * **D6 fix:** dropped `className` and `methodName` from the key. They
19
+ * were redundant — if two different method *bodies* hash to the same
20
+ * SHA-256, they are byte-identical and the LLM's answer would be too.
21
+ * Including names also broke cache sharing on refactors that renamed
22
+ * a method without changing its body. (Names are still passed to the
23
+ * LLM as context inside the prompt; we just don't key the cache on
24
+ * them.)
25
+ *
26
+ * **D6 also adds `language`:** the same byte-identical snippet means
27
+ * very different things in Java vs Kotlin vs Scala — without language
28
+ * in the key, a Java result could be reused for a Kotlin call. Likely
29
+ * benign in practice but a correctness gap worth closing.
19
30
  *
20
- * Cache directory: `.cognium/cache/discovery/` (separate from the
21
- * verify-phase `.cognium/cache/verify/` so each phase can be cleared
22
- * independently `rm -rf .cognium/cache/discovery/` only nukes
23
- * discovery entries).
31
+ * **D2 fix:** uses the discovery-only model fingerprint instead of the
32
+ * joint disc+verify+component fingerprint, so swapping the verify
33
+ * model doesn't invalidate discovery results.
24
34
  *
25
- * Invalidation matrix (#134 acceptance criteria):
26
- * - Edit one method → only that method's entry invalidates
27
- * (methodCode SHA-256 is part of the key)
28
- * - Add a new CWE → existing entries still hit for old CWE-sets;
29
- * new CWE-set requests miss
30
- * - Change disc model → entire cache invalidates
31
- * (fingerprint is part of the singleton key)
35
+ * Cache namespace: `discovery` (separate from `tree` and `verify`).
32
36
  *
33
37
  * Env toggles:
34
- * LLM_DISCOVERY_CACHE=0 → disable persistent discovery cache
35
- * (in-memory dedup from #136 still applies)
38
+ * LLM_DISCOVERY_CACHE=0 → disable persistent discovery cache.
36
39
  */
37
40
  import * as crypto from 'crypto';
38
41
  import * as path from 'path';
39
42
  import { ClassificationCache } from './classification-cache.js';
40
- import { getDefaultLLMConfig, getPhaseModelFingerprint } from '../llm/config.js';
41
- const DISCOVERY_CACHE_SUBDIR = path.join('.cognium', 'cache', 'discovery');
43
+ import { getDefaultLLMConfig, getDiscoveryModelFingerprint } from '../llm/config.js';
44
+ const DISCOVERY_CACHE_SUBDIR = path.join('.cognium', 'cache');
42
45
  /**
43
- * Module-scoped singleton distinct from the discovery-phase singleton
44
- * in `classification-cache.ts` and the verify-phase singleton in
45
- * `verify-cache.ts` so each phase can carry its own model fingerprint
46
- * (e.g. cheap discovery + strong verifier) without thrashing.
46
+ * Prompt-version sentinel for discovery. Bump when the discovery prompt
47
+ * template materially changes (e.g. new few-shot examples, different
48
+ * instructions for `exploitable`, new output schema).
47
49
  */
50
+ const PROMPT_VER = 'disc-v1';
48
51
  let _instance = null;
49
52
  let _instanceFingerprint = '';
50
53
  /**
51
54
  * Get the discovery-phase persistent cache, keyed by per-phase model
52
- * fingerprint. When `LLM_DISCOVERY_CACHE=0` returns a disabled cache that
53
- * no-ops on get/set (callers don't need to branch).
55
+ * fingerprint. When `LLM_DISCOVERY_CACHE=0` returns a disabled cache.
54
56
  */
55
57
  export function getDiscoveryCache(config = getDefaultLLMConfig()) {
56
58
  const enabled = process.env.LLM_DISCOVERY_CACHE !== '0';
57
- const fingerprint = getPhaseModelFingerprint(config);
59
+ const fingerprint = getDiscoveryModelFingerprint(config);
58
60
  if (!_instance || _instanceFingerprint !== fingerprint || _instance.getModelFingerprint() !== fingerprint) {
59
61
  _instance = new ClassificationCache({
62
+ namespace: 'discovery',
60
63
  cacheDir: path.join(process.cwd(), DISCOVERY_CACHE_SUBDIR),
61
64
  modelFingerprint: fingerprint,
62
65
  enabled,
@@ -73,23 +76,28 @@ export function resetDiscoveryCache() {
73
76
  /**
74
77
  * Compute the `(content, classifier)` tuple for the underlying
75
78
  * ClassificationCache. The fingerprint dimension is folded in by the
76
- * cache itself (see classification-cache.ts:computeKey).
79
+ * cache itself.
77
80
  *
78
81
  * Components:
79
- * - classNamedisambiguates same-named methods across classes
80
- * - methodName — per-method granularity (matches the per-method LLM call)
81
- * - methodCode SHA-256 — method edit invalidates only that method's entry
82
+ * - methodCode SHA-256 method edit invalidates only that entry
82
83
  * - sortedCweSet — different CWE-set requests on the same method don't
83
- * reuse each other's prompts (different system prompt, different answer)
84
- * - classifier 'discovery-method' namespace for future
85
- * 'discovery-file' / 'discovery-class' tiers without collision
84
+ * reuse each other's prompts
85
+ * - languageJava vs Kotlin etc. (D6 fix)
86
+ * - PROMPT_VER — global discovery-prompt invalidator
87
+ *
88
+ * Note: `className` / `methodName` are intentionally NOT in the key
89
+ * (D6 fix). They're prompt-context, not identity.
86
90
  */
87
91
  export function computeDiscoveryCacheKey(input) {
88
92
  const methodSha = crypto.createHash('sha256').update(input.methodCode).digest('hex');
89
93
  const sortedCweSet = [...input.targetCWEs].sort().join(',');
90
94
  return {
91
- content: `${input.className}\0${input.methodName}\0${methodSha}\0${sortedCweSet}`,
95
+ content: [methodSha, sortedCweSet, input.language, PROMPT_VER].join('\0'),
92
96
  classifier: 'discovery-method',
93
97
  };
94
98
  }
99
+ /** Test-only: expose the prompt-version sentinel. */
100
+ export function getDiscoveryCachePromptVersion() {
101
+ return PROMPT_VER;
102
+ }
95
103
  //# sourceMappingURL=discovery-cache.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"discovery-cache.js","sourceRoot":"","sources":["../../src/cache/discovery-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;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,sBAAsB,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;AAE3E;;;;;GAKG;AACH,IAAI,SAAS,GAAgD,IAAI,CAAC;AAClE,IAAI,oBAAoB,GAAG,EAAE,CAAC;AAE9B;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,SAAoB,mBAAmB,EAAE;IAEzC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,GAAG,CAAC;IACxD,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,CAAkB;YACnD,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,sBAAsB,CAAC;YAC1D,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,mBAAmB;IACjC,SAAS,GAAG,IAAI,CAAC;IACjB,oBAAoB,GAAG,EAAE,CAAC;AAC5B,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,wBAAwB,CAAC,KAKxC;IACC,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrF,MAAM,YAAY,GAAG,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5D,OAAO;QACL,OAAO,EAAE,GAAG,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,UAAU,KAAK,SAAS,KAAK,YAAY,EAAE;QACjF,UAAU,EAAE,kBAAkB;KAC/B,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"discovery-cache.js","sourceRoot":"","sources":["../../src/cache/discovery-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;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,4BAA4B,EAAkB,MAAM,kBAAkB,CAAC;AAGrG,MAAM,sBAAsB,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AAE9D;;;;GAIG;AACH,MAAM,UAAU,GAAG,SAAS,CAAC;AAE7B,IAAI,SAAS,GAAgD,IAAI,CAAC;AAClE,IAAI,oBAAoB,GAAG,EAAE,CAAC;AAE9B;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,SAAoB,mBAAmB,EAAE;IAEzC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,GAAG,CAAC;IACxD,MAAM,WAAW,GAAG,4BAA4B,CAAC,MAAM,CAAC,CAAC;IAEzD,IAAI,CAAC,SAAS,IAAI,oBAAoB,KAAK,WAAW,IAAI,SAAS,CAAC,mBAAmB,EAAE,KAAK,WAAW,EAAE,CAAC;QAC1G,SAAS,GAAG,IAAI,mBAAmB,CAAkB;YACnD,SAAS,EAAE,WAAW;YACtB,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,sBAAsB,CAAC;YAC1D,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,mBAAmB;IACjC,SAAS,GAAG,IAAI,CAAC;IACjB,oBAAoB,GAAG,EAAE,CAAC;AAC5B,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,wBAAwB,CAAC,KAIxC;IACC,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrF,MAAM,YAAY,GAAG,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5D,OAAO;QACL,OAAO,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACzE,UAAU,EAAE,kBAAkB;KAC/B,CAAC;AACJ,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,8BAA8B;IAC5C,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -3,4 +3,8 @@
3
3
  */
4
4
  export { FileCache, getAnalysisCache, resetAnalysisCache } from './file-cache.js';
5
5
  export type { CacheEntry, FileCacheOptions } from './file-cache.js';
6
+ export { ClassificationCache, getClassificationCache, resetClassificationCache } from './classification-cache.js';
7
+ export type { ClassificationCacheOptions } from './classification-cache.js';
8
+ export type { CacheBackend } from './backend.js';
9
+ export { LocalFSBackend, MemoryBackend, R2Backend, makeBackend, getBackendKind } from './backends/index.js';
6
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAClF,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAClF,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEpE,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAClH,YAAY,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAG5E,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
@@ -2,4 +2,6 @@
2
2
  * Cache module exports
3
3
  */
4
4
  export { FileCache, getAnalysisCache, resetAnalysisCache } from './file-cache.js';
5
+ export { ClassificationCache, getClassificationCache, resetClassificationCache } from './classification-cache.js';
6
+ export { LocalFSBackend, MemoryBackend, R2Backend, makeBackend, getBackendKind } from './backends/index.js';
5
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGlF,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAKlH,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}