circle-ir-ai 4.7.0 → 4.8.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 CHANGED
@@ -5,6 +5,36 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [4.8.0] - 2026-08-26
9
+
10
+ ### Added — cognium-ai#117: Specifica-driven per-repo sink-class allowlist
11
+
12
+ Repo owners can declare, in the Specifica `principles.md`, that a specific method
13
+ is not a real sink for a given finding class (a "Sink semantics" block). The
14
+ scanner reads `.specifica/principles.md` and moves matching findings out of the
15
+ main set into `ScanResult.suppressedBySpecifica[]` — auditable, NOT dropped; each
16
+ carries `suppressed_by_specifica`. Matching is conservative (type + declared
17
+ method invoked in the sink + declared class present). New pure module
18
+ `specifica/sink-suppression.ts` (`parseSinkSuppressions` / `applySinkSuppressions`,
19
+ exported). Zero overhead + no behavior change when no declarations exist.
20
+
21
+ ### Fixed — skillsregistry#65: api_base_url_hijack must not fire on non-public hosts (CWE-494 FP)
22
+
23
+ A non-public host cannot be a public MITM relay. New `isNonPublicHost()` guard on
24
+ the `api_base_url_hijack` detector excludes `.local` (RFC 6762), reserved TLDs
25
+ (RFC 2606/6761), private/loopback/link-local IPv4, and single-label hosts. FP
26
+ (`baseUrl = 'https://tenant.creatio.local'`) → CLEAN; genuine public relay still
27
+ fires (recall preserved); the sr#65 configurable-exclusion unchanged.
28
+
29
+ ### Changed — circle-ir 4.9.8 → 4.9.9 (performance, cognium-ai#305)
30
+
31
+ Large C#/Java single-file taint analysis was superlinear (~16k-line C# file ~37s;
32
+ very large generated files could appear to hang). circle-ir 4.9.9 removes six hot
33
+ paths in the taint/sink text-scan layer → ~11× faster, sub-quadratic scaling,
34
+ with **0 change in `taint.flows`** across OWASP-Java/SecuriBench/BenchmarkPython
35
+ (4101 files) — behavior-preserving. Directly addresses the #305 large-repo hangs.
36
+ OWASP 100% preserved.
37
+
8
38
  ## [4.7.0] - 2026-08-25
9
39
 
10
40
  ### Added — cognium-ai#336: graph-path gate for library/tool context (verifier over-affirmation FP fix)
@@ -24,36 +24,36 @@ export declare const enrichmentAgent: Agent<"enrichment-agent", {
24
24
  indicators: string[];
25
25
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "classify-role", unknown>;
26
26
  discoverSources: import("@mastra/core/tools").Tool<{
27
+ methodCode: string;
27
28
  methodName: string;
28
29
  classRole: string;
29
30
  existingSources: string;
30
- methodCode: string;
31
31
  }, {
32
32
  sources: {
33
- confidence: number;
34
- reasoning: string;
35
- type: string;
36
33
  line: number;
37
34
  variable: string;
35
+ type: string;
36
+ confidence: number;
37
+ reasoning: string;
38
38
  }[];
39
39
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "discover-sources", unknown>;
40
40
  discoverSinks: import("@mastra/core/tools").Tool<{
41
+ methodCode: string;
41
42
  methodName: string;
42
43
  methodCalls: string;
43
44
  existingSinks: string;
44
- methodCode: string;
45
45
  }, {
46
46
  sinks: {
47
- confidence: number;
48
- reasoning: string;
49
- type: string;
50
47
  line: number;
51
48
  method: string;
49
+ type: string;
52
50
  cwe: string;
53
51
  argPositions: number[];
52
+ confidence: number;
53
+ reasoning: string;
54
54
  }[];
55
55
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "discover-sinks", unknown>;
56
- }, undefined, unknown, import("@mastra/core/agent").AgentEditorConfig | undefined>;
56
+ }, undefined, any, import("@mastra/core/agent").AgentEditorConfig | undefined>;
57
57
  /**
58
58
  * Verification Agent
59
59
  *
@@ -62,26 +62,26 @@ export declare const enrichmentAgent: Agent<"enrichment-agent", {
62
62
  */
63
63
  export declare const verificationAgent: Agent<"verification-agent", {
64
64
  verifyVulnerability: import("@mastra/core/tools").Tool<{
65
- cwe: string;
66
- sourceType: string;
67
- className: string;
68
- methodName: string;
69
- methodCode: string;
70
- sourceLine: number;
71
65
  sourceCode: string;
72
- sinkLine: number;
66
+ sourceLine: number;
67
+ sourceType: string;
73
68
  sinkCode: string;
69
+ sinkLine: number;
74
70
  sinkType: string;
71
+ cwe: string;
72
+ methodCode: string;
73
+ methodName: string;
74
+ className: string;
75
75
  sanitizersInPath: string[];
76
76
  }, {
77
+ verdict: "TRUE_POSITIVE" | "FALSE_POSITIVE" | "UNCERTAIN";
77
78
  confidence: number;
78
79
  reasoning: string;
79
- verdict: "TRUE_POSITIVE" | "FALSE_POSITIVE" | "UNCERTAIN";
80
80
  exploitability: "high" | "medium" | "low" | "none";
81
81
  sanitizersFound: string[];
82
82
  attackVector: string;
83
83
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "verify-vulnerability", unknown>;
84
- }, undefined, unknown, import("@mastra/core/agent").AgentEditorConfig | undefined>;
84
+ }, undefined, any, import("@mastra/core/agent").AgentEditorConfig | undefined>;
85
85
  /**
86
86
  * Cross-File Analysis Agent
87
87
  *
@@ -89,26 +89,26 @@ export declare const verificationAgent: Agent<"verification-agent", {
89
89
  */
90
90
  export declare const crossFileAgent: Agent<"cross-file-agent", {
91
91
  crossFileTaint: import("@mastra/core/tools").Tool<{
92
+ sourceFile: string;
92
93
  sourceCode: string;
93
94
  targetFile: string;
95
+ targetCode: string;
94
96
  exportedTaint: {
95
97
  symbol: string;
96
98
  type: string;
97
99
  line: number;
98
100
  }[];
99
- sourceFile: string;
100
- targetCode: string;
101
101
  importedSymbols: string[];
102
102
  }, {
103
- reasoning: string;
104
103
  taintFlows: {
105
- confidence: number;
106
104
  sourceSymbol: string;
107
105
  targetSymbol: string;
108
106
  flowType: "direct" | "transitive" | "conditional";
107
+ confidence: number;
109
108
  }[];
109
+ reasoning: string;
110
110
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "cross-file-taint", unknown>;
111
- }, undefined, unknown, import("@mastra/core/agent").AgentEditorConfig | undefined>;
111
+ }, undefined, any, import("@mastra/core/agent").AgentEditorConfig | undefined>;
112
112
  /**
113
113
  * Orchestrator Agent
114
114
  *
@@ -127,76 +127,76 @@ export declare const orchestratorAgent: Agent<"orchestrator-agent", {
127
127
  indicators: string[];
128
128
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "classify-role", unknown>;
129
129
  discoverSources: import("@mastra/core/tools").Tool<{
130
+ methodCode: string;
130
131
  methodName: string;
131
132
  classRole: string;
132
133
  existingSources: string;
133
- methodCode: string;
134
134
  }, {
135
135
  sources: {
136
- confidence: number;
137
- reasoning: string;
138
- type: string;
139
136
  line: number;
140
137
  variable: string;
138
+ type: string;
139
+ confidence: number;
140
+ reasoning: string;
141
141
  }[];
142
142
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "discover-sources", unknown>;
143
143
  discoverSinks: import("@mastra/core/tools").Tool<{
144
+ methodCode: string;
144
145
  methodName: string;
145
146
  methodCalls: string;
146
147
  existingSinks: string;
147
- methodCode: string;
148
148
  }, {
149
149
  sinks: {
150
- confidence: number;
151
- reasoning: string;
152
- type: string;
153
150
  line: number;
154
151
  method: string;
152
+ type: string;
155
153
  cwe: string;
156
154
  argPositions: number[];
155
+ confidence: number;
156
+ reasoning: string;
157
157
  }[];
158
158
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "discover-sinks", unknown>;
159
159
  verifyVulnerability: import("@mastra/core/tools").Tool<{
160
- cwe: string;
161
- sourceType: string;
162
- className: string;
163
- methodName: string;
164
- methodCode: string;
165
- sourceLine: number;
166
160
  sourceCode: string;
167
- sinkLine: number;
161
+ sourceLine: number;
162
+ sourceType: string;
168
163
  sinkCode: string;
164
+ sinkLine: number;
169
165
  sinkType: string;
166
+ cwe: string;
167
+ methodCode: string;
168
+ methodName: string;
169
+ className: string;
170
170
  sanitizersInPath: string[];
171
171
  }, {
172
+ verdict: "TRUE_POSITIVE" | "FALSE_POSITIVE" | "UNCERTAIN";
172
173
  confidence: number;
173
174
  reasoning: string;
174
- verdict: "TRUE_POSITIVE" | "FALSE_POSITIVE" | "UNCERTAIN";
175
175
  exploitability: "high" | "medium" | "low" | "none";
176
176
  sanitizersFound: string[];
177
177
  attackVector: string;
178
178
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "verify-vulnerability", unknown>;
179
179
  crossFileTaint: import("@mastra/core/tools").Tool<{
180
+ sourceFile: string;
180
181
  sourceCode: string;
181
182
  targetFile: string;
183
+ targetCode: string;
182
184
  exportedTaint: {
183
185
  symbol: string;
184
186
  type: string;
185
187
  line: number;
186
188
  }[];
187
- sourceFile: string;
188
- targetCode: string;
189
189
  importedSymbols: string[];
190
190
  }, {
191
- reasoning: string;
192
191
  taintFlows: {
193
- confidence: number;
194
192
  sourceSymbol: string;
195
193
  targetSymbol: string;
196
194
  flowType: "direct" | "transitive" | "conditional";
195
+ confidence: number;
197
196
  }[];
197
+ reasoning: string;
198
198
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "cross-file-taint", unknown>;
199
- }, undefined, unknown, import("@mastra/core/agent").AgentEditorConfig | undefined>;
199
+ }, undefined, any, import("@mastra/core/agent").AgentEditorConfig | undefined>;
200
200
  export declare const agents: {
201
201
  enrichment: Agent<"enrichment-agent", {
202
202
  classifyRole: import("@mastra/core/tools").Tool<{
@@ -211,80 +211,80 @@ export declare const agents: {
211
211
  indicators: string[];
212
212
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "classify-role", unknown>;
213
213
  discoverSources: import("@mastra/core/tools").Tool<{
214
+ methodCode: string;
214
215
  methodName: string;
215
216
  classRole: string;
216
217
  existingSources: string;
217
- methodCode: string;
218
218
  }, {
219
219
  sources: {
220
- confidence: number;
221
- reasoning: string;
222
- type: string;
223
220
  line: number;
224
221
  variable: string;
222
+ type: string;
223
+ confidence: number;
224
+ reasoning: string;
225
225
  }[];
226
226
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "discover-sources", unknown>;
227
227
  discoverSinks: import("@mastra/core/tools").Tool<{
228
+ methodCode: string;
228
229
  methodName: string;
229
230
  methodCalls: string;
230
231
  existingSinks: string;
231
- methodCode: string;
232
232
  }, {
233
233
  sinks: {
234
- confidence: number;
235
- reasoning: string;
236
- type: string;
237
234
  line: number;
238
235
  method: string;
236
+ type: string;
239
237
  cwe: string;
240
238
  argPositions: number[];
239
+ confidence: number;
240
+ reasoning: string;
241
241
  }[];
242
242
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "discover-sinks", unknown>;
243
- }, undefined, unknown, import("@mastra/core/agent").AgentEditorConfig | undefined>;
243
+ }, undefined, any, import("@mastra/core/agent").AgentEditorConfig | undefined>;
244
244
  verification: Agent<"verification-agent", {
245
245
  verifyVulnerability: import("@mastra/core/tools").Tool<{
246
- cwe: string;
247
- sourceType: string;
248
- className: string;
249
- methodName: string;
250
- methodCode: string;
251
- sourceLine: number;
252
246
  sourceCode: string;
253
- sinkLine: number;
247
+ sourceLine: number;
248
+ sourceType: string;
254
249
  sinkCode: string;
250
+ sinkLine: number;
255
251
  sinkType: string;
252
+ cwe: string;
253
+ methodCode: string;
254
+ methodName: string;
255
+ className: string;
256
256
  sanitizersInPath: string[];
257
257
  }, {
258
+ verdict: "TRUE_POSITIVE" | "FALSE_POSITIVE" | "UNCERTAIN";
258
259
  confidence: number;
259
260
  reasoning: string;
260
- verdict: "TRUE_POSITIVE" | "FALSE_POSITIVE" | "UNCERTAIN";
261
261
  exploitability: "high" | "medium" | "low" | "none";
262
262
  sanitizersFound: string[];
263
263
  attackVector: string;
264
264
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "verify-vulnerability", unknown>;
265
- }, undefined, unknown, import("@mastra/core/agent").AgentEditorConfig | undefined>;
265
+ }, undefined, any, import("@mastra/core/agent").AgentEditorConfig | undefined>;
266
266
  crossFile: Agent<"cross-file-agent", {
267
267
  crossFileTaint: import("@mastra/core/tools").Tool<{
268
+ sourceFile: string;
268
269
  sourceCode: string;
269
270
  targetFile: string;
271
+ targetCode: string;
270
272
  exportedTaint: {
271
273
  symbol: string;
272
274
  type: string;
273
275
  line: number;
274
276
  }[];
275
- sourceFile: string;
276
- targetCode: string;
277
277
  importedSymbols: string[];
278
278
  }, {
279
- reasoning: string;
280
279
  taintFlows: {
281
- confidence: number;
282
280
  sourceSymbol: string;
283
281
  targetSymbol: string;
284
282
  flowType: "direct" | "transitive" | "conditional";
283
+ confidence: number;
285
284
  }[];
285
+ reasoning: string;
286
286
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "cross-file-taint", unknown>;
287
- }, undefined, unknown, import("@mastra/core/agent").AgentEditorConfig | undefined>;
287
+ }, undefined, any, import("@mastra/core/agent").AgentEditorConfig | undefined>;
288
288
  orchestrator: Agent<"orchestrator-agent", {
289
289
  classifyRole: import("@mastra/core/tools").Tool<{
290
290
  className: string;
@@ -298,76 +298,76 @@ export declare const agents: {
298
298
  indicators: string[];
299
299
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "classify-role", unknown>;
300
300
  discoverSources: import("@mastra/core/tools").Tool<{
301
+ methodCode: string;
301
302
  methodName: string;
302
303
  classRole: string;
303
304
  existingSources: string;
304
- methodCode: string;
305
305
  }, {
306
306
  sources: {
307
- confidence: number;
308
- reasoning: string;
309
- type: string;
310
307
  line: number;
311
308
  variable: string;
309
+ type: string;
310
+ confidence: number;
311
+ reasoning: string;
312
312
  }[];
313
313
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "discover-sources", unknown>;
314
314
  discoverSinks: import("@mastra/core/tools").Tool<{
315
+ methodCode: string;
315
316
  methodName: string;
316
317
  methodCalls: string;
317
318
  existingSinks: string;
318
- methodCode: string;
319
319
  }, {
320
320
  sinks: {
321
- confidence: number;
322
- reasoning: string;
323
- type: string;
324
321
  line: number;
325
322
  method: string;
323
+ type: string;
326
324
  cwe: string;
327
325
  argPositions: number[];
326
+ confidence: number;
327
+ reasoning: string;
328
328
  }[];
329
329
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "discover-sinks", unknown>;
330
330
  verifyVulnerability: import("@mastra/core/tools").Tool<{
331
- cwe: string;
332
- sourceType: string;
333
- className: string;
334
- methodName: string;
335
- methodCode: string;
336
- sourceLine: number;
337
331
  sourceCode: string;
338
- sinkLine: number;
332
+ sourceLine: number;
333
+ sourceType: string;
339
334
  sinkCode: string;
335
+ sinkLine: number;
340
336
  sinkType: string;
337
+ cwe: string;
338
+ methodCode: string;
339
+ methodName: string;
340
+ className: string;
341
341
  sanitizersInPath: string[];
342
342
  }, {
343
+ verdict: "TRUE_POSITIVE" | "FALSE_POSITIVE" | "UNCERTAIN";
343
344
  confidence: number;
344
345
  reasoning: string;
345
- verdict: "TRUE_POSITIVE" | "FALSE_POSITIVE" | "UNCERTAIN";
346
346
  exploitability: "high" | "medium" | "low" | "none";
347
347
  sanitizersFound: string[];
348
348
  attackVector: string;
349
349
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "verify-vulnerability", unknown>;
350
350
  crossFileTaint: import("@mastra/core/tools").Tool<{
351
+ sourceFile: string;
351
352
  sourceCode: string;
352
353
  targetFile: string;
354
+ targetCode: string;
353
355
  exportedTaint: {
354
356
  symbol: string;
355
357
  type: string;
356
358
  line: number;
357
359
  }[];
358
- sourceFile: string;
359
- targetCode: string;
360
360
  importedSymbols: string[];
361
361
  }, {
362
- reasoning: string;
363
362
  taintFlows: {
364
- confidence: number;
365
363
  sourceSymbol: string;
366
364
  targetSymbol: string;
367
365
  flowType: "direct" | "transitive" | "conditional";
366
+ confidence: number;
368
367
  }[];
368
+ reasoning: string;
369
369
  }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "cross-file-taint", unknown>;
370
- }, undefined, unknown, import("@mastra/core/agent").AgentEditorConfig | undefined>;
370
+ }, undefined, any, import("@mastra/core/agent").AgentEditorConfig | undefined>;
371
371
  };
372
372
  export default agents;
373
373
  //# sourceMappingURL=agents.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../src/agents/mastra/agents.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AA8N3C;;;;;GAKG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kFA2B1B,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;kFAyB5B,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;kFAqBzB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kFA0B5B,CAAC;AAMH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKlB,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../src/agents/mastra/agents.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AA8N3C;;;;;GAKG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8EA2B1B,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;8EAyB5B,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;8EAqBzB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8EA0B5B,CAAC;AAMH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKlB,CAAC;AAEF,eAAe,MAAM,CAAC"}