@rigour-labs/core 6.4.1 → 6.4.3
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/dist/deep/code-pass.d.ts +4 -0
- package/dist/deep/code-pass.js +14 -4
- package/dist/deep/code-pass.test.js +2 -0
- package/dist/gates/deep-analysis.d.ts +6 -0
- package/dist/gates/deep-analysis.js +9 -1
- package/dist/gates/deep-runner.js +2 -0
- package/dist/gates/deep-timeout.test.d.ts +1 -0
- package/dist/gates/deep-timeout.test.js +10 -0
- package/dist/gates/logic-drift.d.ts +8 -3
- package/dist/gates/logic-drift.js +10 -5
- package/dist/gates/logic-drift.test.js +7 -0
- package/dist/gates/promise-safety.js +3 -1
- package/dist/gates/promise-safety.test.d.ts +1 -0
- package/dist/gates/promise-safety.test.js +34 -0
- package/dist/gates/security-patterns-data.js +2 -1
- package/dist/gates/security-patterns.test.js +8 -0
- package/dist/templates/universal-config.js +2 -2
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.js +4 -2
- package/package.json +9 -6
package/dist/deep/code-pass.d.ts
CHANGED
|
@@ -21,5 +21,9 @@ export interface CodePassConfig extends PassConfig {
|
|
|
21
21
|
}
|
|
22
22
|
export interface CodePassResult extends PassResult {
|
|
23
23
|
contexts: CodeContext[];
|
|
24
|
+
/** Findings the model proposed, before the self-check (the max and cloud tiers). */
|
|
25
|
+
proposed: number;
|
|
26
|
+
/** Of those, withdrawn by the self-check. */
|
|
27
|
+
withdrawn: number;
|
|
24
28
|
}
|
|
25
29
|
export declare function runCodePass(provider: InferenceProvider, facts: FileFacts[], config: CodePassConfig): Promise<CodePassResult>;
|
package/dist/deep/code-pass.js
CHANGED
|
@@ -11,7 +11,7 @@ import { buildReferencePack } from './reference-pack.js';
|
|
|
11
11
|
import { selfCheck } from './self-check.js';
|
|
12
12
|
import { Logger } from '../utils/logger.js';
|
|
13
13
|
export async function runCodePass(provider, facts, config) {
|
|
14
|
-
const result = { findings: [], chunksTotal: facts.length, chunksFailed: 0, contexts: [] };
|
|
14
|
+
const result = { findings: [], chunksTotal: facts.length, chunksFailed: 0, contexts: [], proposed: 0, withdrawn: 0 };
|
|
15
15
|
for (let i = 0; i < facts.length; i++) {
|
|
16
16
|
const file = facts[i];
|
|
17
17
|
config.onProgress?.(` Reviewing ${file.path} (${i + 1}/${facts.length})...`);
|
|
@@ -32,7 +32,17 @@ export async function runCodePass(provider, facts, config) {
|
|
|
32
32
|
context = { ...context, source: `${context.source}\n${pack.source}` };
|
|
33
33
|
result.contexts.push(context);
|
|
34
34
|
try {
|
|
35
|
-
|
|
35
|
+
if (pack) {
|
|
36
|
+
const checked = await reviewTwiceAndCheck(provider, context, pack, config);
|
|
37
|
+
result.findings.push(...checked.kept);
|
|
38
|
+
result.proposed += checked.proposed;
|
|
39
|
+
result.withdrawn += checked.withdrawn;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const found = await reviewOnce(provider, context, '', config);
|
|
43
|
+
result.findings.push(...found);
|
|
44
|
+
result.proposed += found.length;
|
|
45
|
+
}
|
|
36
46
|
}
|
|
37
47
|
catch (error) {
|
|
38
48
|
recordFailure(result, `${file.path}: ${error.message}`, config);
|
|
@@ -48,11 +58,11 @@ async function reviewTwiceAndCheck(provider, context, pack, config) {
|
|
|
48
58
|
const second = pack.sections.length > 1 ? await reviewOnce(provider, context, [...pack.sections].reverse().join('\n\n'), config) : [];
|
|
49
59
|
const union = dedupe([...first, ...second]);
|
|
50
60
|
if (union.length === 0)
|
|
51
|
-
return union;
|
|
61
|
+
return { kept: union, proposed: 0, withdrawn: 0 };
|
|
52
62
|
const checked = await selfCheck(provider, context, pack.text, union, config.inference);
|
|
53
63
|
if (checked.withdrawn > 0)
|
|
54
64
|
config.onProgress?.(` Self-check withdrew ${checked.withdrawn} of ${union.length} finding(s) in ${context.file}.`);
|
|
55
|
-
return checked.kept;
|
|
65
|
+
return { kept: checked.kept, proposed: union.length, withdrawn: checked.withdrawn };
|
|
56
66
|
}
|
|
57
67
|
function packFor(file, config) {
|
|
58
68
|
const reference = config.reference;
|
|
@@ -39,6 +39,7 @@ describe('runCodePass', () => {
|
|
|
39
39
|
const result = await run(provider);
|
|
40
40
|
expect(prompts).toHaveLength(1);
|
|
41
41
|
expect(result.findings.map(f => f.line)).toEqual([3]);
|
|
42
|
+
expect([result.proposed, result.withdrawn]).toEqual([1, 0]);
|
|
42
43
|
});
|
|
43
44
|
it('does not repeat an identical pass when there is only one reference section', async () => {
|
|
44
45
|
const { provider, prompts } = fakeProvider([[]], []);
|
|
@@ -60,6 +61,7 @@ describe('runCodePass', () => {
|
|
|
60
61
|
expect(reviews[1].indexOf('REMOVED by this change')).toBeLessThan(reviews[1].indexOf('PR DESCRIPTION'));
|
|
61
62
|
expect(prompts.filter(p => p.startsWith('You reported a defect'))).toHaveLength(2);
|
|
62
63
|
expect(result.findings.map(f => [f.line, f.category])).toEqual([[3, 'correctness']]);
|
|
64
|
+
expect([result.proposed, result.withdrawn]).toEqual([2, 1]); // two distinct findings, one withdrawn
|
|
63
65
|
});
|
|
64
66
|
it('reads a self-check reply only when it is a verdict', () => {
|
|
65
67
|
expect(parseVerdict('{"real": false, "reason": "handled"}')).toBe(false);
|
|
@@ -31,6 +31,9 @@ export interface DeepRunOutcome {
|
|
|
31
31
|
filesAnalyzed: number;
|
|
32
32
|
chunksTotal: number;
|
|
33
33
|
chunksFailed: number;
|
|
34
|
+
/** Code mode: findings the model proposed, and how many the self-check withdrew. */
|
|
35
|
+
findingsProposed?: number;
|
|
36
|
+
findingsWithdrawn?: number;
|
|
34
37
|
/** Model actually used (the stock fallback is named as such). */
|
|
35
38
|
model?: string;
|
|
36
39
|
modelFallback?: boolean;
|
|
@@ -55,3 +58,6 @@ export declare class DeepAnalysisGate extends Gate {
|
|
|
55
58
|
private createCloudAgent;
|
|
56
59
|
private toFailure;
|
|
57
60
|
}
|
|
61
|
+
/** Per-call options; unset config falls back to per-provider defaults. */
|
|
62
|
+
/** Per-call inference timeout: a local 7B reads a file with its reference pack far slower than the small tiers. */
|
|
63
|
+
export declare function defaultTimeout(options: DeepOptions): number;
|
|
@@ -111,6 +111,8 @@ export class DeepAnalysisGate extends Gate {
|
|
|
111
111
|
onProgress: this.config.onProgress,
|
|
112
112
|
});
|
|
113
113
|
this.recordPass(result);
|
|
114
|
+
this.outcome.findingsProposed = result.proposed;
|
|
115
|
+
this.outcome.findingsWithdrawn = result.withdrawn;
|
|
114
116
|
return verifyCodeFindings(result.findings, result.contexts);
|
|
115
117
|
}
|
|
116
118
|
/** The max and cloud tiers read reference material and review twice; the small models do not. */
|
|
@@ -175,12 +177,18 @@ function isCloud(options) {
|
|
|
175
177
|
return !!options.apiKey && !!options.provider && options.provider !== 'local';
|
|
176
178
|
}
|
|
177
179
|
/** Per-call options; unset config falls back to per-provider defaults. */
|
|
180
|
+
/** Per-call inference timeout: a local 7B reads a file with its reference pack far slower than the small tiers. */
|
|
181
|
+
export function defaultTimeout(options) {
|
|
182
|
+
if (isCloud(options))
|
|
183
|
+
return 120_000;
|
|
184
|
+
return options.max ? 240_000 : 60_000;
|
|
185
|
+
}
|
|
178
186
|
function inferenceOptions(config) {
|
|
179
187
|
const cloud = isCloud(config.options);
|
|
180
188
|
return {
|
|
181
189
|
maxTokens: config.maxTokens ?? (cloud ? 4096 : 1024),
|
|
182
190
|
temperature: config.temperature ?? 0.1,
|
|
183
|
-
timeout: config.timeoutMs ?? (
|
|
191
|
+
timeout: config.timeoutMs ?? defaultTimeout(config.options),
|
|
184
192
|
jsonMode: true,
|
|
185
193
|
};
|
|
186
194
|
}
|
|
@@ -46,6 +46,8 @@ export async function runDeepAnalysis(config, context, deepOptions) {
|
|
|
46
46
|
chunks_total: outcome.chunksTotal,
|
|
47
47
|
chunks_failed: outcome.chunksFailed,
|
|
48
48
|
error: outcome.error,
|
|
49
|
+
findings_proposed: outcome.findingsProposed,
|
|
50
|
+
findings_withdrawn: outcome.findingsWithdrawn,
|
|
49
51
|
findings_count: findings.length,
|
|
50
52
|
findings_verified: findings.filter(f => f.verified).length,
|
|
51
53
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { defaultTimeout } from './deep-analysis.js';
|
|
3
|
+
describe('deep inference timeout', () => {
|
|
4
|
+
it('gives the local 7B tier four minutes a call, the small tiers one, and cloud two', () => {
|
|
5
|
+
expect(defaultTimeout({ enabled: true })).toBe(60_000);
|
|
6
|
+
expect(defaultTimeout({ enabled: true, pro: true })).toBe(60_000);
|
|
7
|
+
expect(defaultTimeout({ enabled: true, max: true })).toBe(240_000);
|
|
8
|
+
expect(defaultTimeout({ enabled: true, apiKey: 'k', provider: 'claude' })).toBe(120_000);
|
|
9
|
+
});
|
|
10
|
+
});
|
|
@@ -3,9 +3,14 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Detects when AI subtly changes business logic in functions:
|
|
5
5
|
* - Comparison operator mutations: >= became > (off-by-one)
|
|
6
|
-
* - Return statement additions/removals
|
|
7
|
-
* - Branch count changes
|
|
8
|
-
*
|
|
6
|
+
* - Return statement additions/removals (opt-in: track_returns)
|
|
7
|
+
* - Branch count changes, new if/else added or removed (opt-in: track_branches)
|
|
8
|
+
*
|
|
9
|
+
* Return and branch counts are off by default: a change that edits a function
|
|
10
|
+
* usually changes them on purpose, so they fired on almost every edited function
|
|
11
|
+
* without saying what was wrong. Judged against review comments developers acted
|
|
12
|
+
* on, 0 of 7 such findings raised the reviewer's issue. An operator mutation is
|
|
13
|
+
* specific and actionable, so it stays on.
|
|
9
14
|
*
|
|
10
15
|
* This is the HARDEST drift to catch because:
|
|
11
16
|
* - Code still compiles
|
|
@@ -3,9 +3,14 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Detects when AI subtly changes business logic in functions:
|
|
5
5
|
* - Comparison operator mutations: >= became > (off-by-one)
|
|
6
|
-
* - Return statement additions/removals
|
|
7
|
-
* - Branch count changes
|
|
8
|
-
*
|
|
6
|
+
* - Return statement additions/removals (opt-in: track_returns)
|
|
7
|
+
* - Branch count changes, new if/else added or removed (opt-in: track_branches)
|
|
8
|
+
*
|
|
9
|
+
* Return and branch counts are off by default: a change that edits a function
|
|
10
|
+
* usually changes them on purpose, so they fired on almost every edited function
|
|
11
|
+
* without saying what was wrong. Judged against review comments developers acted
|
|
12
|
+
* on, 0 of 7 such findings raised the reviewer's issue. An operator mutation is
|
|
13
|
+
* specific and actionable, so it stays on.
|
|
9
14
|
*
|
|
10
15
|
* This is the HARDEST drift to catch because:
|
|
11
16
|
* - Code still compiles
|
|
@@ -34,8 +39,8 @@ export class LogicDriftGate extends Gate {
|
|
|
34
39
|
enabled: config.enabled ?? true,
|
|
35
40
|
baseline_path: config.baseline_path ?? '.rigour/logic-baseline.json',
|
|
36
41
|
track_operators: config.track_operators ?? true,
|
|
37
|
-
track_branches: config.track_branches ??
|
|
38
|
-
track_returns: config.track_returns ??
|
|
42
|
+
track_branches: config.track_branches ?? false,
|
|
43
|
+
track_returns: config.track_returns ?? false,
|
|
39
44
|
};
|
|
40
45
|
}
|
|
41
46
|
get provenance() { return 'ai-drift'; }
|
|
@@ -35,6 +35,13 @@ describe('LogicDriftGate Git baseline', () => {
|
|
|
35
35
|
git('merge', '-q', '--ff-only', 'feature');
|
|
36
36
|
expect(await gate.run({ cwd })).toEqual([]);
|
|
37
37
|
}, 30_000);
|
|
38
|
+
it('reports return and branch count changes only when opted in', async () => {
|
|
39
|
+
git('switch', '-q', '-c', 'feature');
|
|
40
|
+
fs.writeFileSync(path.join(cwd, 'src/rules.ts'), 'export function eligible(score: number) {\n if (score < 0) return false;\n if (score > 100) return false;\n return score >= 10;\n}\n');
|
|
41
|
+
expect(await new LogicDriftGate().run({ cwd })).toEqual([]);
|
|
42
|
+
const opted = await new LogicDriftGate({ track_returns: true, track_branches: true }).run({ cwd });
|
|
43
|
+
expect(opted.map(f => f.title).sort()).toEqual(['Logic Drift: Branch Change', 'Logic Drift: Return Change']);
|
|
44
|
+
}, 30_000);
|
|
38
45
|
it('does not use a moving local snapshot when Git has no main reference', async () => {
|
|
39
46
|
git('switch', '-q', '-c', 'feature');
|
|
40
47
|
git('branch', '-D', 'main');
|
|
@@ -104,7 +104,9 @@ export class PromiseSafetyGate extends Gate {
|
|
|
104
104
|
// Also count .then().then().catch() chains — the catch at the end covers all
|
|
105
105
|
if (j > i && braceDepth < 0)
|
|
106
106
|
break; // Exited enclosing scope
|
|
107
|
-
|
|
107
|
+
// A statement keyword ends the chain only at the chain's own depth; inside the
|
|
108
|
+
// .then callback's body (depth > 0) `if`/`return` belong to the callback.
|
|
109
|
+
if (j > i && braceDepth <= 0 && /^(?:const|let|var|function|class|export|import|if|for|while|return)\b/.test(lookahead.trim()))
|
|
108
110
|
break;
|
|
109
111
|
}
|
|
110
112
|
if (!hasCatch && !isInsideTryBlock(lines, i) && !/(?:const|let|var)\s+\w+\s*=/.test(line)) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
5
|
+
import { PromiseSafetyGate } from './promise-safety.js';
|
|
6
|
+
describe('PromiseSafetyGate unhandled .then', () => {
|
|
7
|
+
let cwd;
|
|
8
|
+
beforeEach(() => { cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'promise-safety-')); });
|
|
9
|
+
afterEach(() => { fs.rmSync(cwd, { recursive: true, force: true }); });
|
|
10
|
+
async function thenFindings(code) {
|
|
11
|
+
fs.writeFileSync(path.join(cwd, 'session.ts'), code);
|
|
12
|
+
const failures = await new PromiseSafetyGate().run({ cwd });
|
|
13
|
+
return failures.filter(f => f.details.includes('unhandled-then')).length;
|
|
14
|
+
}
|
|
15
|
+
it('flags a .then chain with no .catch', async () => {
|
|
16
|
+
expect(await thenFindings('export function wake(p: Promise<number>) {\n p.then(n => {\n if (n > 1) log(n);\n });\n}\ndeclare function log(n: number): void;\n')).toBe(1);
|
|
17
|
+
});
|
|
18
|
+
it('finds the .catch that closes a chain whose callback body has if and return statements', async () => {
|
|
19
|
+
const code = [
|
|
20
|
+
'export function wake(accepted: Promise<{ action: string }>) {',
|
|
21
|
+
' void accepted',
|
|
22
|
+
' .then(result => {',
|
|
23
|
+
" if (result.action === 'wake') {",
|
|
24
|
+
' return run();',
|
|
25
|
+
' }',
|
|
26
|
+
' return undefined;',
|
|
27
|
+
' })',
|
|
28
|
+
' .catch(() => {});',
|
|
29
|
+
'}',
|
|
30
|
+
'declare function run(): Promise<void>;',
|
|
31
|
+
].join('\n');
|
|
32
|
+
expect(await thenFindings(code)).toBe(0);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -67,7 +67,8 @@ export const VULNERABILITY_PATTERNS = [
|
|
|
67
67
|
// Hardcoded Secrets
|
|
68
68
|
{
|
|
69
69
|
type: 'hardcoded_secrets',
|
|
70
|
-
|
|
70
|
+
// A secret literal has no whitespace: `hidePassword: 'Hide password'` is a UI label, not a credential.
|
|
71
|
+
regex: /(?:password|secret|api_key|apikey|auth_token|access_token|private_key)\s*[:=]\s*['"][^'"\s]{8,}['"]/gi,
|
|
71
72
|
severity: 'critical',
|
|
72
73
|
description: 'Hardcoded secret detected in code',
|
|
73
74
|
cwe: 'CWE-798',
|
|
@@ -85,6 +85,14 @@ describe('SecurityPatternsGate', () => {
|
|
|
85
85
|
const vulns = await checkSecurityPatterns(filePath);
|
|
86
86
|
expect(vulns.some(v => v.type === 'hardcoded_secrets')).toBe(true);
|
|
87
87
|
});
|
|
88
|
+
it('does not take a UI label that mentions a password for a secret', async () => {
|
|
89
|
+
const filePath = path.join(testDir, 'be.ts');
|
|
90
|
+
fs.writeFileSync(filePath, `
|
|
91
|
+
export default { authForm: { hidePassword: 'Схаваць пароль', showPassword: 'Show the password' } };
|
|
92
|
+
`);
|
|
93
|
+
const vulns = await checkSecurityPatterns(filePath);
|
|
94
|
+
expect(vulns.some(v => v.type === 'hardcoded_secrets')).toBe(false);
|
|
95
|
+
});
|
|
88
96
|
it('should detect password assignments', async () => {
|
|
89
97
|
const filePath = path.join(testDir, 'auth.ts');
|
|
90
98
|
fs.writeFileSync(filePath, `
|
|
@@ -231,8 +231,8 @@ export const UNIVERSAL_CONFIG = {
|
|
|
231
231
|
enabled: true,
|
|
232
232
|
baseline_path: '.rigour/logic-baseline.json',
|
|
233
233
|
track_operators: true,
|
|
234
|
-
track_branches:
|
|
235
|
-
track_returns:
|
|
234
|
+
track_branches: false,
|
|
235
|
+
track_returns: false,
|
|
236
236
|
},
|
|
237
237
|
semantic_bugs: {
|
|
238
238
|
enabled: true,
|
package/dist/types/index.d.ts
CHANGED
|
@@ -3023,6 +3023,8 @@ export declare const ReportSchema: z.ZodObject<{
|
|
|
3023
3023
|
chunks_total: z.ZodOptional<z.ZodNumber>;
|
|
3024
3024
|
chunks_failed: z.ZodOptional<z.ZodNumber>;
|
|
3025
3025
|
error: z.ZodOptional<z.ZodString>;
|
|
3026
|
+
findings_proposed: z.ZodOptional<z.ZodNumber>;
|
|
3027
|
+
findings_withdrawn: z.ZodOptional<z.ZodNumber>;
|
|
3026
3028
|
findings_count: z.ZodOptional<z.ZodNumber>;
|
|
3027
3029
|
findings_verified: z.ZodOptional<z.ZodNumber>;
|
|
3028
3030
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -3037,6 +3039,8 @@ export declare const ReportSchema: z.ZodObject<{
|
|
|
3037
3039
|
files_analyzed?: number | undefined;
|
|
3038
3040
|
chunks_total?: number | undefined;
|
|
3039
3041
|
chunks_failed?: number | undefined;
|
|
3042
|
+
findings_proposed?: number | undefined;
|
|
3043
|
+
findings_withdrawn?: number | undefined;
|
|
3040
3044
|
findings_count?: number | undefined;
|
|
3041
3045
|
findings_verified?: number | undefined;
|
|
3042
3046
|
}, {
|
|
@@ -3051,6 +3055,8 @@ export declare const ReportSchema: z.ZodObject<{
|
|
|
3051
3055
|
files_analyzed?: number | undefined;
|
|
3052
3056
|
chunks_total?: number | undefined;
|
|
3053
3057
|
chunks_failed?: number | undefined;
|
|
3058
|
+
findings_proposed?: number | undefined;
|
|
3059
|
+
findings_withdrawn?: number | undefined;
|
|
3054
3060
|
findings_count?: number | undefined;
|
|
3055
3061
|
findings_verified?: number | undefined;
|
|
3056
3062
|
}>>;
|
|
@@ -3068,6 +3074,8 @@ export declare const ReportSchema: z.ZodObject<{
|
|
|
3068
3074
|
files_analyzed?: number | undefined;
|
|
3069
3075
|
chunks_total?: number | undefined;
|
|
3070
3076
|
chunks_failed?: number | undefined;
|
|
3077
|
+
findings_proposed?: number | undefined;
|
|
3078
|
+
findings_withdrawn?: number | undefined;
|
|
3071
3079
|
findings_count?: number | undefined;
|
|
3072
3080
|
findings_verified?: number | undefined;
|
|
3073
3081
|
} | undefined;
|
|
@@ -3097,6 +3105,8 @@ export declare const ReportSchema: z.ZodObject<{
|
|
|
3097
3105
|
files_analyzed?: number | undefined;
|
|
3098
3106
|
chunks_total?: number | undefined;
|
|
3099
3107
|
chunks_failed?: number | undefined;
|
|
3108
|
+
findings_proposed?: number | undefined;
|
|
3109
|
+
findings_withdrawn?: number | undefined;
|
|
3100
3110
|
findings_count?: number | undefined;
|
|
3101
3111
|
findings_verified?: number | undefined;
|
|
3102
3112
|
} | undefined;
|
|
@@ -3128,6 +3138,8 @@ export declare const ReportSchema: z.ZodObject<{
|
|
|
3128
3138
|
files_analyzed?: number | undefined;
|
|
3129
3139
|
chunks_total?: number | undefined;
|
|
3130
3140
|
chunks_failed?: number | undefined;
|
|
3141
|
+
findings_proposed?: number | undefined;
|
|
3142
|
+
findings_withdrawn?: number | undefined;
|
|
3131
3143
|
findings_count?: number | undefined;
|
|
3132
3144
|
findings_verified?: number | undefined;
|
|
3133
3145
|
} | undefined;
|
|
@@ -3176,6 +3188,8 @@ export declare const ReportSchema: z.ZodObject<{
|
|
|
3176
3188
|
files_analyzed?: number | undefined;
|
|
3177
3189
|
chunks_total?: number | undefined;
|
|
3178
3190
|
chunks_failed?: number | undefined;
|
|
3191
|
+
findings_proposed?: number | undefined;
|
|
3192
|
+
findings_withdrawn?: number | undefined;
|
|
3179
3193
|
findings_count?: number | undefined;
|
|
3180
3194
|
findings_verified?: number | undefined;
|
|
3181
3195
|
} | undefined;
|
package/dist/types/index.js
CHANGED
|
@@ -295,8 +295,8 @@ export const GatesSchema = z.object({
|
|
|
295
295
|
enabled: z.boolean().optional().default(true),
|
|
296
296
|
baseline_path: z.string().optional().default('.rigour/logic-baseline.json'),
|
|
297
297
|
track_operators: z.boolean().optional().default(true),
|
|
298
|
-
track_branches: z.boolean().optional().default(
|
|
299
|
-
track_returns: z.boolean().optional().default(
|
|
298
|
+
track_branches: z.boolean().optional().default(false), // opt-in: counts change on purpose in most edits
|
|
299
|
+
track_returns: z.boolean().optional().default(false), // opt-in: same
|
|
300
300
|
}).optional().default({}),
|
|
301
301
|
// v4.0+ Deep Analysis (LLM-powered)
|
|
302
302
|
deep: z.object({
|
|
@@ -422,6 +422,8 @@ export const ReportSchema = z.object({
|
|
|
422
422
|
chunks_total: z.number().optional(),
|
|
423
423
|
chunks_failed: z.number().optional(),
|
|
424
424
|
error: z.string().optional(),
|
|
425
|
+
findings_proposed: z.number().optional(), // code mode, before the self-check
|
|
426
|
+
findings_withdrawn: z.number().optional(), // by the self-check
|
|
425
427
|
findings_count: z.number().optional(),
|
|
426
428
|
findings_verified: z.number().optional(),
|
|
427
429
|
}).optional(),
|
package/package.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rigour-labs/core",
|
|
3
|
-
"version": "6.4.
|
|
3
|
+
"version": "6.4.3",
|
|
4
4
|
"description": "AI-native quality gate engine with local Bayesian learning. AST analysis, drift detection, Fix Packet generation, and agent self-healing across TypeScript, JavaScript, Python, Go, Ruby, and C#.",
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": ">=22"
|
|
7
|
+
},
|
|
5
8
|
"license": "MIT",
|
|
6
9
|
"homepage": "https://rigour.run",
|
|
7
10
|
"keywords": [
|
|
@@ -67,11 +70,11 @@
|
|
|
67
70
|
"pg": "^8.16.3",
|
|
68
71
|
"sqlite3": "^5.1.7",
|
|
69
72
|
"openai": "^4.104.0",
|
|
70
|
-
"@rigour-labs/brain-darwin-
|
|
71
|
-
"@rigour-labs/brain-darwin-
|
|
72
|
-
"@rigour-labs/brain-linux-
|
|
73
|
-
"@rigour-labs/brain-
|
|
74
|
-
"@rigour-labs/brain-
|
|
73
|
+
"@rigour-labs/brain-darwin-x64": "6.4.3",
|
|
74
|
+
"@rigour-labs/brain-darwin-arm64": "6.4.3",
|
|
75
|
+
"@rigour-labs/brain-linux-arm64": "6.4.3",
|
|
76
|
+
"@rigour-labs/brain-linux-x64": "6.4.3",
|
|
77
|
+
"@rigour-labs/brain-win-x64": "6.4.3"
|
|
75
78
|
},
|
|
76
79
|
"devDependencies": {
|
|
77
80
|
"@types/fs-extra": "^11.0.4",
|