circle-ir-ai 2.17.0 → 2.18.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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,124 @@ 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
+ ## [2.18.1] - 2026-06-23
9
+
10
+ ### Dependencies
11
+
12
+ - Bump `circle-ir` `3.93.0` → `3.95.0`.
13
+
14
+ ### What this pulls in
15
+
16
+ `circle-ir@3.94.0` shipped the `SastFinding.confidence` tri-state
17
+ field (`'high' | 'medium' | 'low'`) and the per-file
18
+ speculative-finding suppression infrastructure that the upcoming
19
+ `missing-sanitizer-gate` pass will use. Pre-3.94.0 passes leave the
20
+ field undefined and are treated as `'high'` (always emitted), so
21
+ scanner output is unchanged today.
22
+
23
+ `circle-ir@3.95.0` adds `AnalyzerOptions.enableEntryPointGate?:
24
+ boolean` (default `true`) — an opt-out toggle for the Java
25
+ entry-point classifier gate that suppresses
26
+ `interprocedural_param` taint sources on library-API methods not
27
+ reachable from a recognised HTTP / RPC / lifecycle entry point.
28
+ Java-only; no-op for other languages regardless of toggle state.
29
+ `circle-ir-ai` does not yet thread this flag through the mastra
30
+ workflow or scanner facade — callers that need the un-gated source
31
+ set can pass it directly via the `circle-ir` `analyze()` /
32
+ `InterproceduralPass` constructor.
33
+
34
+ ### Verification
35
+
36
+ - `npm run build` — clean.
37
+ - Tests unchanged (900 pass + 3 skipped).
38
+
39
+ No API shape change in `circle-ir-ai`.
40
+
41
+ ## [2.18.0] - 2026-06-22
42
+
43
+ ### Added — findings-emission instrumentation env wiring (cognium-dev#145 PR C)
44
+
45
+ `circle-ir-ai` now honors the `CIRCLE_IR_INSTRUMENT_FINDINGS=1`
46
+ environment variable at analyzer-init time, flipping
47
+ `setFindingsInstrumentation(true)` on `circle-ir`'s opt-in
48
+ findings-emission hook. With the env var set, every call into
49
+ `circle-ir`'s `analyze()` — from both the scanner static path and the
50
+ mastra `runPatternMatch` LLM path — emits one `[finding]` JSON line on
51
+ stderr per `SastFinding` plus one `[findings-summary]` line per file.
52
+
53
+ Each `[finding]` payload carries the fields required to re-derive
54
+ coalesce candidates for cognium-dev#143 after the fact:
55
+
56
+ ```jsonc
57
+ {
58
+ "file": "VulnServlet.java",
59
+ "line": 9,
60
+ "rule_id": "sql-injection-jdbc",
61
+ "pass": "TaintMatcherPass",
62
+ "category": "security",
63
+ "severity": "high",
64
+ "cwe": "CWE-89",
65
+ "sink_type": "sql-query",
66
+ "source_type": "http-param",
67
+ "confidence": 0.95,
68
+ "dedup_group_id": "VulnServlet.java:9:sql-injection-jdbc"
69
+ }
70
+ ```
71
+
72
+ Per-file summary payload:
73
+
74
+ ```jsonc
75
+ {
76
+ "file": "VulnServlet.java",
77
+ "total": 3,
78
+ "unique_groups": 2,
79
+ "max_findings_per_group": 2,
80
+ "sources_count": 1,
81
+ "sinks_count": 1,
82
+ "by_rule": { "sql-injection-jdbc": 3 },
83
+ "by_severity": { "high": 3 }
84
+ }
85
+ ```
86
+
87
+ The wiring lives in `src/utils/analyzer-init.ts` so any call into
88
+ `ensureAnalyzerInitialized()` — which both `scanner.ts` and mastra's
89
+ `runPatternMatch()` already use — applies the env var idempotently. No
90
+ public API change; `setFindingsInstrumentation()` remains the
91
+ programmatic entry point for non-CLI consumers.
92
+
93
+ Output is `console.error` (per the upstream hook contract — see
94
+ `circle-ir/dist/analysis/findings-instrumentation.js:13-15`). Redirect
95
+ stderr to capture: `CIRCLE_IR_INSTRUMENT_FINDINGS=1 cognium-ai scan ./src
96
+ 2> findings.jsonl`. The flag is fully no-op when unset; no perf or
97
+ allocation overhead on the default path.
98
+
99
+ ### Why this matters
100
+
101
+ The empirical data collected here informs the **cognium-dev#143
102
+ "coalesce candidates"** decision. The `dedup_group_id` field plus per-
103
+ file `max_findings_per_group` count let us measure how often
104
+ `(file, line, rule_id)` clusters actually receive multiple
105
+ near-duplicate emissions in the wild. That measurement is the gating
106
+ input for whether circle-ir's findings pipeline should add a
107
+ post-emit coalesce pass or leave the existing dedup logic alone.
108
+
109
+ ### Verification
110
+
111
+ - `npm run build` — clean.
112
+ - `npm run typecheck` — clean.
113
+ - `npm test` — **900 / 900 pass + 3 skipped** (+2 new tests
114
+ `findings-instrumentation.test.ts` covering both env states).
115
+ - Manual: `CIRCLE_IR_INSTRUMENT_FINDINGS=1 ...` emits `[finding]` and
116
+ `[findings-summary]` lines on stderr; unsetting suppresses both.
117
+
118
+ ### Why minor (`2.17.0 → 2.18.0`)
119
+
120
+ Additive: new env-var honored at init time, no removed or renamed
121
+ exports, no change to the default observable output. Downstream
122
+ packages (`cognium-ai`, `@cognium-ai/mcp-server`, `circle-pack`) need a
123
+ dep range bump but no source-side change to benefit — setting the env
124
+ var is enough.
125
+
8
126
  ## [2.17.0] - 2026-06-22
9
127
 
10
128
  ### Dependencies
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer-init.d.ts","sourceRoot":"","sources":["../../src/utils/analyzer-init.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAuC,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AAKtF;;;GAGG;AACH,wBAAsB,yBAAyB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBjG;AAGD,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"analyzer-init.d.ts","sourceRoot":"","sources":["../../src/utils/analyzer-init.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,WAAW,CAAC;AAgCnB;;;GAGG;AACH,wBAAsB,yBAAyB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BjG;AAGD,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC"}
@@ -5,14 +5,44 @@
5
5
  * This fixes issues when cognium-ai is installed globally or in various
6
6
  * node_modules configurations.
7
7
  */
8
- import { initAnalyzer, isAnalyzerInitialized } from 'circle-ir';
8
+ import { initAnalyzer, isAnalyzerInitialized, setFindingsInstrumentation, } from 'circle-ir';
9
9
  import { getWasmAnalyzerOptions } from './wasm-path.js';
10
10
  let initializationPromise = null;
11
+ let instrumentationApplied = false;
12
+ /**
13
+ * cognium-dev#145 PR C — honor `CIRCLE_IR_INSTRUMENT_FINDINGS=1` at
14
+ * analyzer-init time so every path that hits circle-ir's `analyze()`
15
+ * (scanner static path + mastra `runPatternMatch` LLM path) emits the
16
+ * per-file `[finding]` / `[findings-summary]` JSON lines on stderr.
17
+ *
18
+ * `circle-ir`'s library does not read the env var itself — only its
19
+ * own CLI does. We translate the env var to `setFindingsInstrumentation(true)`
20
+ * here so cognium-ai runs honor the same opt-in toggle without each CLI
21
+ * needing to re-implement the wiring.
22
+ *
23
+ * Idempotent: only flips the toggle on once per process even though
24
+ * `ensureAnalyzerInitialized` may be called many times. Never disables
25
+ * the flag — external `setFindingsInstrumentation(false)` calls still
26
+ * take effect.
27
+ */
28
+ function applyInstrumentationEnv() {
29
+ if (instrumentationApplied) {
30
+ return;
31
+ }
32
+ instrumentationApplied = true;
33
+ if (process.env.CIRCLE_IR_INSTRUMENT_FINDINGS === '1') {
34
+ setFindingsInstrumentation(true);
35
+ }
36
+ }
11
37
  /**
12
38
  * Initialize the analyzer with proper WASM path resolution.
13
39
  * Safe to call multiple times - will only initialize once.
14
40
  */
15
41
  export async function ensureAnalyzerInitialized(options) {
42
+ // Apply instrumentation toggle on every call (cheap, idempotent) so the
43
+ // env-var check happens even when the analyzer was warmed by an unrelated
44
+ // import path.
45
+ applyInstrumentationEnv();
16
46
  if (isAnalyzerInitialized()) {
17
47
  return;
18
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer-init.js","sourceRoot":"","sources":["../../src/utils/analyzer-init.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAwB,MAAM,WAAW,CAAC;AACtF,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAExD,IAAI,qBAAqB,GAAyB,IAAI,CAAC;AAEvD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,OAAkC;IAChF,IAAI,qBAAqB,EAAE,EAAE,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,IAAI,qBAAqB,EAAE,CAAC;QAC1B,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IAED,qBAAqB,GAAG,CAAC,KAAK,IAAI,EAAE;QAClC,gDAAgD;QAChD,MAAM,WAAW,GAAG,sBAAsB,EAAE,CAAC;QAE7C,uCAAuC;QACvC,MAAM,aAAa,GAAoB;YACrC,GAAG,WAAW;YACd,GAAG,OAAO;SACX,CAAC;QAEF,MAAM,YAAY,CAAC,aAAa,CAAC,CAAC;IACpC,CAAC,CAAC,EAAE,CAAC;IAEL,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED,4BAA4B;AAC5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"analyzer-init.js","sourceRoot":"","sources":["../../src/utils/analyzer-init.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,0BAA0B,GAE3B,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAExD,IAAI,qBAAqB,GAAyB,IAAI,CAAC;AACvD,IAAI,sBAAsB,GAAG,KAAK,CAAC;AAEnC;;;;;;;;;;;;;;;GAeG;AACH,SAAS,uBAAuB;IAC9B,IAAI,sBAAsB,EAAE,CAAC;QAC3B,OAAO;IACT,CAAC;IACD,sBAAsB,GAAG,IAAI,CAAC;IAC9B,IAAI,OAAO,CAAC,GAAG,CAAC,6BAA6B,KAAK,GAAG,EAAE,CAAC;QACtD,0BAA0B,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,OAAkC;IAChF,wEAAwE;IACxE,0EAA0E;IAC1E,eAAe;IACf,uBAAuB,EAAE,CAAC;IAE1B,IAAI,qBAAqB,EAAE,EAAE,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,IAAI,qBAAqB,EAAE,CAAC;QAC1B,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IAED,qBAAqB,GAAG,CAAC,KAAK,IAAI,EAAE;QAClC,gDAAgD;QAChD,MAAM,WAAW,GAAG,sBAAsB,EAAE,CAAC;QAE7C,uCAAuC;QACvC,MAAM,aAAa,GAAoB;YACrC,GAAG,WAAW;YACd,GAAG,OAAO;SACX,CAAC;QAEF,MAAM,YAAY,CAAC,aAAa,CAAC,CAAC;IACpC,CAAC,CAAC,EAAE,CAAC;IAEL,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED,4BAA4B;AAC5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "circle-ir-ai",
3
- "version": "2.17.0",
3
+ "version": "2.18.1",
4
4
  "description": "LLM-enhanced SAST analysis built on circle-ir",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -95,7 +95,7 @@
95
95
  "dependencies": {
96
96
  "@ax-llm/ax": "^20.0.0",
97
97
  "@mastra/core": "^1.18.0",
98
- "circle-ir": "3.90.0",
98
+ "circle-ir": "3.95.0",
99
99
  "minimatch": "^10.2.5",
100
100
  "p-queue": "^9.1.0"
101
101
  },