circle-ir-ai 4.19.0 → 4.20.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 +19 -0
- package/dist/coverage/index.d.ts +50 -0
- package/dist/coverage/index.d.ts.map +1 -0
- package/dist/coverage/index.js +73 -0
- package/dist/coverage/index.js.map +1 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -116,6 +116,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
116
116
|
Unchanged on 4.9.29: OWASP 1415/1415, Juliet 243/243, SecuriBench 97.2%/6.7%, Go 89.5%,
|
|
117
117
|
NodeJS 92.9%, CWE-Bench-Rust 100%, bash and HTML 100%.
|
|
118
118
|
|
|
119
|
+
## [4.20.0] - 2026-10-07
|
|
120
|
+
|
|
121
|
+
### Changed
|
|
122
|
+
- **`circle-ir` 4.10.0 → 4.11.0**, a minor, so this is a minor. The pin is what
|
|
123
|
+
`src/mcp/index.ts` reads for the tool module's `circleIrRange`, so the module now
|
|
124
|
+
declares **4.11.0**. Verified on the built module: `circle-ir-ai/mcp 4.20.0 4.11.0`.
|
|
125
|
+
- **What 4.11.0 changes:** cognium-dev#292 drops taint flows whose only source is a bare
|
|
126
|
+
function parameter (`interprocedural_param`) for every language except Java and C#,
|
|
127
|
+
unless the enclosing function is a recognised framework handler. Sources are kept; only
|
|
128
|
+
flows go. Opt back in with `AnalyzerOptions.speculativeParamSources`. Also #516 (a Python
|
|
129
|
+
`for` target bound from a tainted iterable is a source).
|
|
130
|
+
- **No benchmark moved.** All fifteen static suites were run on 4.10.0 and 4.11.0
|
|
131
|
+
back to back and score identically: OWASP 1415/1415, Juliet 243/243, NodeJS 92.9%,
|
|
132
|
+
Rust 92.3% (100% TPR), CWE-Bench-Rust 100%, Bash and HTML 100%, Go 89.5%, Firing Range
|
|
133
|
+
92.1% TPR, NodeGoat / Juice Shop / DVPWA 100%, PyGoat 90.0%, DVNA 71.4%, C# synthetic
|
|
134
|
+
75.0%. The gate is not exercised by these corpora; library-API and agent-code scans
|
|
135
|
+
(the skill scanner's input) are where it can remove flows, and they are not measured here.
|
|
136
|
+
- 2,428 tests pass unchanged against 4.11.0 (196 files, 4 skipped); typecheck clean.
|
|
137
|
+
|
|
119
138
|
## [4.19.0] - 2026-10-02
|
|
120
139
|
|
|
121
140
|
### Changed
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coverage map — the Conformis architect-view *receipt* (conformis-layer-
|
|
3
|
+
* generation-canon.md §9, conformis-execution-plan.md D9 "the subtraction + the
|
|
4
|
+
* receipt").
|
|
5
|
+
*
|
|
6
|
+
* Given a layer-BOM (what's in the repo per layer), declare for each component
|
|
7
|
+
* whether we can *witness* it today (`settles_now`), can only *signal* it until
|
|
8
|
+
* a dynamic harness exists (`signal_until_harness`), have declared it
|
|
9
|
+
* un-checkable (`not_diffable`), or have no capability mapped (`uncovered`).
|
|
10
|
+
*
|
|
11
|
+
* HONESTY (canon §11): these states are a **declaration** of intended coverage,
|
|
12
|
+
* grounded in the canon's per-layer inherited/extracted split — NOT proven
|
|
13
|
+
* witness yield. The real settled-% comes later from shadow-mode witness runs.
|
|
14
|
+
* So this emits **counts + per-component verdicts** (the receipt), and a
|
|
15
|
+
* `declaredCoverablePct` explicitly labelled projected, never a settled-%.
|
|
16
|
+
*/
|
|
17
|
+
import type { BomLayer, RepoBom } from '../bom/types.js';
|
|
18
|
+
export type CoverageState = 'settles_now' | 'signal_until_harness' | 'not_diffable' | 'uncovered';
|
|
19
|
+
export declare const COVERAGE_STATES: CoverageState[];
|
|
20
|
+
export interface ComponentCoverage {
|
|
21
|
+
name: string;
|
|
22
|
+
layer: BomLayer;
|
|
23
|
+
kind: string;
|
|
24
|
+
state: CoverageState;
|
|
25
|
+
/** Short why, e.g. "static call-site asserts" / "needs replay harness". */
|
|
26
|
+
basis: string;
|
|
27
|
+
}
|
|
28
|
+
export interface LayerCoverage {
|
|
29
|
+
layer: BomLayer;
|
|
30
|
+
title: string;
|
|
31
|
+
counts: Record<CoverageState, number>;
|
|
32
|
+
components: ComponentCoverage[];
|
|
33
|
+
}
|
|
34
|
+
export interface CoverageMap {
|
|
35
|
+
target: string;
|
|
36
|
+
layers: Record<BomLayer, LayerCoverage>;
|
|
37
|
+
summary: {
|
|
38
|
+
counts: Record<CoverageState, number>;
|
|
39
|
+
totalComponents: number;
|
|
40
|
+
/**
|
|
41
|
+
* PROJECTED — (settles_now + signal_until_harness) / (total − not_diffable).
|
|
42
|
+
* A declaration of intended coverage, NOT a proven settled-%. Gate any real
|
|
43
|
+
* % on shadow-mode witness yield (canon §11).
|
|
44
|
+
*/
|
|
45
|
+
declaredCoverablePct: number;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** Compute the coverage-map (receipt) for a BOM. Pure. */
|
|
49
|
+
export declare function computeCoverage(bom: RepoBom): CoverageMap;
|
|
50
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/coverage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAgB,QAAQ,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAGvE,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,sBAAsB,GAAG,cAAc,GAAG,WAAW,CAAC;AAElG,eAAO,MAAM,eAAe,EAAE,aAAa,EAAyE,CAAC;AAErH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,QAAQ,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,aAAa,CAAC;IACrB,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,QAAQ,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACtC,UAAU,EAAE,iBAAiB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACxC,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QACtC,eAAe,EAAE,MAAM,CAAC;QACxB;;;;WAIG;QACH,oBAAoB,EAAE,MAAM,CAAC;KAC9B,CAAC;CACH;AAuCD,0DAA0D;AAC1D,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,WAAW,CA2BzD"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coverage map — the Conformis architect-view *receipt* (conformis-layer-
|
|
3
|
+
* generation-canon.md §9, conformis-execution-plan.md D9 "the subtraction + the
|
|
4
|
+
* receipt").
|
|
5
|
+
*
|
|
6
|
+
* Given a layer-BOM (what's in the repo per layer), declare for each component
|
|
7
|
+
* whether we can *witness* it today (`settles_now`), can only *signal* it until
|
|
8
|
+
* a dynamic harness exists (`signal_until_harness`), have declared it
|
|
9
|
+
* un-checkable (`not_diffable`), or have no capability mapped (`uncovered`).
|
|
10
|
+
*
|
|
11
|
+
* HONESTY (canon §11): these states are a **declaration** of intended coverage,
|
|
12
|
+
* grounded in the canon's per-layer inherited/extracted split — NOT proven
|
|
13
|
+
* witness yield. The real settled-% comes later from shadow-mode witness runs.
|
|
14
|
+
* So this emits **counts + per-component verdicts** (the receipt), and a
|
|
15
|
+
* `declaredCoverablePct` explicitly labelled projected, never a settled-%.
|
|
16
|
+
*/
|
|
17
|
+
import { BOM_LAYER_TITLES } from '../bom/types.js';
|
|
18
|
+
export const COVERAGE_STATES = ['settles_now', 'signal_until_harness', 'not_diffable', 'uncovered'];
|
|
19
|
+
// Per-layer default capability, from the canon §3 verifier-shape / inherited-
|
|
20
|
+
// extracted column. Declarations, extend/override per kind below.
|
|
21
|
+
const LAYER_CAPABILITY = {
|
|
22
|
+
L2: { state: 'signal_until_harness', basis: 'runtime races/async need a replay harness (Coyote/JPF); presence is static' },
|
|
23
|
+
L3: { state: 'settles_now', basis: 'static call-site asserts (alg≠none, PKCE-MUST, state-validated); wire seq is dynamic' },
|
|
24
|
+
L4: { state: 'settles_now', basis: 'reachability × version-diff (Syft/Grype/OSV) — static' },
|
|
25
|
+
L5: { state: 'signal_until_harness', basis: 'framework idiom conformance is fuzzier; wrap linters as signal until harnessed' },
|
|
26
|
+
L6: { state: 'settles_now', basis: 'config-conformance (Checkov/OPA/Conftest) — static' },
|
|
27
|
+
L7: { state: 'signal_until_harness', basis: 'tx-boundary/N+1 static; migration reconciliation needs a differential harness' },
|
|
28
|
+
L8: { state: 'settles_now', basis: 'contract-diff × usage-witness (oasdiff/buf/graphql-inspector + circle-ir) — static usage' },
|
|
29
|
+
L9: { state: 'uncovered', basis: 'domain-logic residual — extracted + executed harness, not yet built' },
|
|
30
|
+
};
|
|
31
|
+
// Per-kind overrides where a component is more/less checkable than its layer default.
|
|
32
|
+
const KIND_CAPABILITY = {
|
|
33
|
+
'runtime:node': { state: 'not_diffable', basis: 'runtime version itself is not a conformance target' },
|
|
34
|
+
'runtime:python': { state: 'not_diffable', basis: 'runtime version itself is not a conformance target' },
|
|
35
|
+
'runtime:jvm': { state: 'not_diffable', basis: 'runtime version itself is not a conformance target' },
|
|
36
|
+
'runtime:go': { state: 'not_diffable', basis: 'runtime version itself is not a conformance target' },
|
|
37
|
+
'runtime:rust': { state: 'not_diffable', basis: 'runtime version itself is not a conformance target' },
|
|
38
|
+
// L7 raw drivers: presence only, no ORM idiom to check
|
|
39
|
+
'db-driver': { state: 'signal_until_harness', basis: 'raw driver — query safety needs taint, no ORM idiom contract' },
|
|
40
|
+
// L4 dev deps: not a runtime supply-chain surface
|
|
41
|
+
'dependency:dev': { state: 'not_diffable', basis: 'dev-only dependency — not in the shipped supply-chain surface' },
|
|
42
|
+
};
|
|
43
|
+
function capabilityFor(c) {
|
|
44
|
+
return KIND_CAPABILITY[c.kind] ?? LAYER_CAPABILITY[c.layer];
|
|
45
|
+
}
|
|
46
|
+
const ALL_LAYERS = ['L2', 'L3', 'L4', 'L5', 'L6', 'L7', 'L8', 'L9'];
|
|
47
|
+
/** Compute the coverage-map (receipt) for a BOM. Pure. */
|
|
48
|
+
export function computeCoverage(bom) {
|
|
49
|
+
const zero = () => ({ settles_now: 0, signal_until_harness: 0, not_diffable: 0, uncovered: 0 });
|
|
50
|
+
const total = zero();
|
|
51
|
+
const layers = {};
|
|
52
|
+
for (const layer of ALL_LAYERS) {
|
|
53
|
+
const counts = zero();
|
|
54
|
+
const components = [];
|
|
55
|
+
for (const c of bom.layers[layer].components) {
|
|
56
|
+
const cap = capabilityFor(c);
|
|
57
|
+
counts[cap.state]++;
|
|
58
|
+
total[cap.state]++;
|
|
59
|
+
components.push({ name: c.name, layer, kind: c.kind, state: cap.state, basis: cap.basis });
|
|
60
|
+
}
|
|
61
|
+
layers[layer] = { layer, title: BOM_LAYER_TITLES[layer], counts, components };
|
|
62
|
+
}
|
|
63
|
+
const totalComponents = COVERAGE_STATES.reduce((n, s) => n + total[s], 0);
|
|
64
|
+
const diffable = totalComponents - total.not_diffable;
|
|
65
|
+
const coverable = total.settles_now + total.signal_until_harness;
|
|
66
|
+
const declaredCoverablePct = diffable > 0 ? Math.round((coverable / diffable) * 1000) / 10 : 0;
|
|
67
|
+
return {
|
|
68
|
+
target: bom.target,
|
|
69
|
+
layers,
|
|
70
|
+
summary: { counts: total, totalComponents, declaredCoverablePct },
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/coverage/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "circle-ir-ai",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.20.0",
|
|
4
4
|
"description": "LLM-enhanced SAST analysis built on circle-ir",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
"@ax-llm/ax": "^20.0.0",
|
|
111
111
|
"@cognium/project-profile-detect": "^1.1.0",
|
|
112
112
|
"@mastra/core": "^1.18.0",
|
|
113
|
-
"circle-ir": "4.
|
|
113
|
+
"circle-ir": "4.11.0",
|
|
114
114
|
"minimatch": "^10.2.5",
|
|
115
115
|
"p-queue": "^9.1.0",
|
|
116
116
|
"zod": "^4.4.3"
|