@rigour-labs/core 4.3.0 → 4.3.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/dist/gates/runner.js +5 -0
- package/dist/gates/side-effect-analysis.d.ts +67 -0
- package/dist/gates/side-effect-analysis.js +559 -0
- package/dist/gates/side-effect-helpers.d.ts +260 -0
- package/dist/gates/side-effect-helpers.js +1096 -0
- package/dist/gates/side-effect-rules.d.ts +39 -0
- package/dist/gates/side-effect-rules.js +302 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/templates/universal-config.js +12 -0
- package/dist/types/index.d.ts +140 -0
- package/dist/types/index.js +14 -0
- package/package.json +6 -6
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Side-Effect Analysis Rules
|
|
3
|
+
*
|
|
4
|
+
* Pattern definitions for detecting unbounded side effects that cause
|
|
5
|
+
* real-world consequences: process spawns, resource exhaustion, circular
|
|
6
|
+
* triggers, missing circuit breakers.
|
|
7
|
+
*
|
|
8
|
+
* Each rule has:
|
|
9
|
+
* - regex patterns per language
|
|
10
|
+
* - a check function that verifies context (surrounding lines)
|
|
11
|
+
* - severity and description
|
|
12
|
+
*
|
|
13
|
+
* @since v4.3.0
|
|
14
|
+
*/
|
|
15
|
+
export type SideEffectLang = 'js' | 'ts' | 'py' | 'go' | 'rs' | 'cs' | 'java' | 'rb';
|
|
16
|
+
export interface SideEffectViolation {
|
|
17
|
+
rule: string;
|
|
18
|
+
severity: 'critical' | 'high' | 'medium' | 'low';
|
|
19
|
+
file: string;
|
|
20
|
+
line: number;
|
|
21
|
+
match: string;
|
|
22
|
+
description: string;
|
|
23
|
+
hint: string;
|
|
24
|
+
}
|
|
25
|
+
export declare const LANG_MAP: Record<string, SideEffectLang>;
|
|
26
|
+
export declare const FILE_GLOBS: string[];
|
|
27
|
+
export declare const TIMER_CREATE_PATTERNS: Record<string, RegExp[]>;
|
|
28
|
+
export declare const TIMER_CLEANUP_PATTERNS: Record<string, RegExp[]>;
|
|
29
|
+
export declare const PROCESS_SPAWN_PATTERNS: Record<string, RegExp[]>;
|
|
30
|
+
export declare const PROCESS_EXIT_PATTERNS: Record<string, RegExp[]>;
|
|
31
|
+
export declare const UNBOUNDED_LOOP_PATTERNS: Record<string, RegExp[]>;
|
|
32
|
+
export declare const IO_PATTERNS: Record<string, RegExp[]>;
|
|
33
|
+
export declare const RETRY_PATTERNS: Record<string, RegExp[]>;
|
|
34
|
+
export declare const MAX_RETRY_INDICATORS: RegExp[];
|
|
35
|
+
export declare const WATCHER_PATTERNS: Record<string, RegExp[]>;
|
|
36
|
+
export declare const WRITE_PATTERNS: Record<string, RegExp[]>;
|
|
37
|
+
export declare const RESOURCE_OPEN_PATTERNS: Record<string, RegExp[]>;
|
|
38
|
+
export declare const RESOURCE_CLOSE_PATTERNS: Record<string, RegExp[]>;
|
|
39
|
+
export declare const AUTO_RESTART_PATTERNS: Record<string, RegExp[]>;
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Side-Effect Analysis Rules
|
|
3
|
+
*
|
|
4
|
+
* Pattern definitions for detecting unbounded side effects that cause
|
|
5
|
+
* real-world consequences: process spawns, resource exhaustion, circular
|
|
6
|
+
* triggers, missing circuit breakers.
|
|
7
|
+
*
|
|
8
|
+
* Each rule has:
|
|
9
|
+
* - regex patterns per language
|
|
10
|
+
* - a check function that verifies context (surrounding lines)
|
|
11
|
+
* - severity and description
|
|
12
|
+
*
|
|
13
|
+
* @since v4.3.0
|
|
14
|
+
*/
|
|
15
|
+
// ── Language detection ──
|
|
16
|
+
export const LANG_MAP = {
|
|
17
|
+
'.ts': 'ts', '.tsx': 'ts', '.mts': 'ts',
|
|
18
|
+
'.js': 'js', '.jsx': 'js', '.mjs': 'js', '.cjs': 'js',
|
|
19
|
+
'.py': 'py',
|
|
20
|
+
'.go': 'go',
|
|
21
|
+
'.rs': 'rs',
|
|
22
|
+
'.cs': 'cs',
|
|
23
|
+
'.java': 'java',
|
|
24
|
+
'.rb': 'rb',
|
|
25
|
+
};
|
|
26
|
+
export const FILE_GLOBS = [
|
|
27
|
+
'**/*.{ts,tsx,mts,js,jsx,mjs,cjs}',
|
|
28
|
+
'**/*.py',
|
|
29
|
+
'**/*.go',
|
|
30
|
+
'**/*.rs',
|
|
31
|
+
'**/*.cs',
|
|
32
|
+
'**/*.java',
|
|
33
|
+
'**/*.rb',
|
|
34
|
+
];
|
|
35
|
+
// ── Timer patterns (setInterval/setTimeout without cleanup) ──
|
|
36
|
+
export const TIMER_CREATE_PATTERNS = {
|
|
37
|
+
js: [
|
|
38
|
+
/\bsetInterval\s*\(/,
|
|
39
|
+
/\bsetTimeout\s*\(/,
|
|
40
|
+
],
|
|
41
|
+
ts: [
|
|
42
|
+
/\bsetInterval\s*\(/,
|
|
43
|
+
/\bsetTimeout\s*\(/,
|
|
44
|
+
],
|
|
45
|
+
py: [
|
|
46
|
+
/\bscheduler\.enter\s*\(/,
|
|
47
|
+
/\bTimer\s*\(/,
|
|
48
|
+
/\bschedule\.every\b/,
|
|
49
|
+
],
|
|
50
|
+
go: [
|
|
51
|
+
/\btime\.NewTicker\s*\(/,
|
|
52
|
+
/\btime\.Tick\s*\(/,
|
|
53
|
+
],
|
|
54
|
+
java: [
|
|
55
|
+
/\bScheduledExecutorService\b/,
|
|
56
|
+
/\bTimer\(\)\.schedule\b/,
|
|
57
|
+
/\bTimer\(\)\.scheduleAtFixedRate\b/,
|
|
58
|
+
],
|
|
59
|
+
rs: [],
|
|
60
|
+
cs: [
|
|
61
|
+
/\bnew\s+Timer\s*\(/,
|
|
62
|
+
/\bSetInterval\s*\(/,
|
|
63
|
+
],
|
|
64
|
+
rb: [],
|
|
65
|
+
};
|
|
66
|
+
export const TIMER_CLEANUP_PATTERNS = {
|
|
67
|
+
js: [/\bclearInterval\s*\(/, /\bclearTimeout\s*\(/],
|
|
68
|
+
ts: [/\bclearInterval\s*\(/, /\bclearTimeout\s*\(/],
|
|
69
|
+
py: [/\.cancel\s*\(/],
|
|
70
|
+
go: [/\.Stop\s*\(/],
|
|
71
|
+
java: [/\.shutdown\s*\(/, /\.cancel\s*\(/],
|
|
72
|
+
rs: [],
|
|
73
|
+
cs: [/\.Dispose\s*\(/, /\.Stop\s*\(/],
|
|
74
|
+
rb: [],
|
|
75
|
+
};
|
|
76
|
+
// ── Process spawn patterns ──
|
|
77
|
+
export const PROCESS_SPAWN_PATTERNS = {
|
|
78
|
+
js: [
|
|
79
|
+
/\bchild_process\.\w+\s*\(/,
|
|
80
|
+
/\bspawn\s*\(/,
|
|
81
|
+
/\bexec\s*\(/,
|
|
82
|
+
/\bexecFile\s*\(/,
|
|
83
|
+
/\bfork\s*\(/,
|
|
84
|
+
/\bexeca\s*\(/,
|
|
85
|
+
],
|
|
86
|
+
ts: [
|
|
87
|
+
/\bchild_process\.\w+\s*\(/,
|
|
88
|
+
/\bspawn\s*\(/,
|
|
89
|
+
/\bexec\s*\(/,
|
|
90
|
+
/\bexecFile\s*\(/,
|
|
91
|
+
/\bfork\s*\(/,
|
|
92
|
+
/\bexeca\s*\(/,
|
|
93
|
+
],
|
|
94
|
+
py: [
|
|
95
|
+
/\bsubprocess\.\w+\s*\(/,
|
|
96
|
+
/\bPopen\s*\(/,
|
|
97
|
+
/\bos\.system\s*\(/,
|
|
98
|
+
/\bos\.exec\w*\s*\(/,
|
|
99
|
+
/\bos\.spawn\w*\s*\(/,
|
|
100
|
+
],
|
|
101
|
+
go: [
|
|
102
|
+
/\bexec\.Command\s*\(/,
|
|
103
|
+
/\bos\/exec\b/,
|
|
104
|
+
/\bcmd\.Start\s*\(/,
|
|
105
|
+
/\bcmd\.Run\s*\(/,
|
|
106
|
+
],
|
|
107
|
+
java: [
|
|
108
|
+
/\bProcessBuilder\b/,
|
|
109
|
+
/\bRuntime\.getRuntime\(\)\.exec\s*\(/,
|
|
110
|
+
],
|
|
111
|
+
rs: [
|
|
112
|
+
/\bCommand::new\s*\(/,
|
|
113
|
+
/\bstd::process::Command\b/,
|
|
114
|
+
],
|
|
115
|
+
cs: [
|
|
116
|
+
/\bProcess\.Start\s*\(/,
|
|
117
|
+
/\bnew\s+ProcessStartInfo\b/,
|
|
118
|
+
],
|
|
119
|
+
rb: [
|
|
120
|
+
/\bsystem\s*\(/,
|
|
121
|
+
/\bspawn\s*\(/,
|
|
122
|
+
/\b`[^`]+`/,
|
|
123
|
+
/\bIO\.popen\s*\(/,
|
|
124
|
+
],
|
|
125
|
+
};
|
|
126
|
+
export const PROCESS_EXIT_PATTERNS = {
|
|
127
|
+
js: [/\.on\s*\(\s*['"](?:exit|close)['"]/, /\.kill\s*\(/, /\.disconnect\s*\(/],
|
|
128
|
+
ts: [/\.on\s*\(\s*['"](?:exit|close)['"]/, /\.kill\s*\(/, /\.disconnect\s*\(/],
|
|
129
|
+
py: [/\.wait\s*\(/, /\.terminate\s*\(/, /\.kill\s*\(/, /\.communicate\s*\(/],
|
|
130
|
+
go: [/\.Wait\s*\(/, /cmd\.Process\.Kill\s*\(/],
|
|
131
|
+
java: [/\.waitFor\s*\(/, /\.destroy\s*\(/, /\.destroyForcibly\s*\(/],
|
|
132
|
+
rs: [/\.wait\s*\(/, /\.kill\s*\(/],
|
|
133
|
+
cs: [/\.WaitForExit\s*\(/, /\.Kill\s*\(/, /\.Close\s*\(/],
|
|
134
|
+
rb: [/Process\.wait\b/, /Process\.kill\b/],
|
|
135
|
+
};
|
|
136
|
+
// ── Unbounded loop patterns ──
|
|
137
|
+
export const UNBOUNDED_LOOP_PATTERNS = {
|
|
138
|
+
js: [/\bwhile\s*\(\s*true\s*\)/, /\bwhile\s*\(\s*1\s*\)/, /\bfor\s*\(\s*;\s*;\s*\)/],
|
|
139
|
+
ts: [/\bwhile\s*\(\s*true\s*\)/, /\bwhile\s*\(\s*1\s*\)/, /\bfor\s*\(\s*;\s*;\s*\)/],
|
|
140
|
+
py: [/\bwhile\s+True\s*:/, /\bwhile\s+1\s*:/],
|
|
141
|
+
go: [/\bfor\s*\{/, /\bfor\s+\{/], // bare `for {` in Go = infinite loop
|
|
142
|
+
java: [/\bwhile\s*\(\s*true\s*\)/, /\bfor\s*\(\s*;\s*;\s*\)/],
|
|
143
|
+
rs: [/\bloop\s*\{/],
|
|
144
|
+
cs: [/\bwhile\s*\(\s*true\s*\)/, /\bfor\s*\(\s*;\s*;\s*\)/],
|
|
145
|
+
rb: [/\bloop\s+do\b/, /\bwhile\s+true\b/],
|
|
146
|
+
};
|
|
147
|
+
// I/O operations inside loops that indicate resource impact
|
|
148
|
+
export const IO_PATTERNS = {
|
|
149
|
+
js: [
|
|
150
|
+
/\bfs\.\w+/, /\bfetch\s*\(/, /\baxios\.\w+/, /\bhttp\.\w+/,
|
|
151
|
+
/\.write\s*\(/, /\.send\s*\(/, /\bchild_process\./,
|
|
152
|
+
/\bconsole\.\w+/, /\bprocess\.stdout/,
|
|
153
|
+
],
|
|
154
|
+
ts: [
|
|
155
|
+
/\bfs\.\w+/, /\bfetch\s*\(/, /\baxios\.\w+/, /\bhttp\.\w+/,
|
|
156
|
+
/\.write\s*\(/, /\.send\s*\(/, /\bchild_process\./,
|
|
157
|
+
],
|
|
158
|
+
py: [
|
|
159
|
+
/\bopen\s*\(/, /\brequests\.\w+/, /\burllib\.\w+/,
|
|
160
|
+
/\bsubprocess\./, /\bos\.\w+/, /\bsocket\.\w+/,
|
|
161
|
+
/\.write\s*\(/, /\bprint\s*\(/,
|
|
162
|
+
],
|
|
163
|
+
go: [
|
|
164
|
+
/\bos\.\w+/, /\bnet\.\w+/, /\bhttp\.\w+/,
|
|
165
|
+
/\bio\.\w+/, /\bfmt\.Fprint/, /\bioutil\.\w+/,
|
|
166
|
+
/\bexec\.Command/,
|
|
167
|
+
],
|
|
168
|
+
java: [
|
|
169
|
+
/\bnew\s+File\w*\(/, /\bHttpClient\b/, /\bSocket\b/,
|
|
170
|
+
/\.write\s*\(/, /\bRuntime\.getRuntime\(\)/,
|
|
171
|
+
],
|
|
172
|
+
rs: [
|
|
173
|
+
/\bstd::fs::/, /\bstd::net::/, /\bstd::process::/,
|
|
174
|
+
/\.write\s*\(/, /\btokio::\w+/,
|
|
175
|
+
],
|
|
176
|
+
cs: [
|
|
177
|
+
/\bFile\.\w+/, /\bHttpClient\b/, /\bProcess\.Start/,
|
|
178
|
+
/\.Write\s*\(/, /\bSocket\b/,
|
|
179
|
+
],
|
|
180
|
+
rb: [
|
|
181
|
+
/\bFile\.\w+/, /\bNet::HTTP\b/, /\bIO\.\w+/,
|
|
182
|
+
/\.write\s*\(/, /\bsystem\s*\(/,
|
|
183
|
+
],
|
|
184
|
+
};
|
|
185
|
+
// ── Retry without limit patterns ──
|
|
186
|
+
export const RETRY_PATTERNS = {
|
|
187
|
+
js: [/\bcatch\s*\([^)]*\)\s*\{/, /\.catch\s*\(/],
|
|
188
|
+
ts: [/\bcatch\s*\([^)]*\)\s*\{/, /\.catch\s*\(/],
|
|
189
|
+
py: [/\bexcept\s+\w+/, /\bexcept\s*:/],
|
|
190
|
+
go: [/\bif\s+err\s*!=\s*nil\b/],
|
|
191
|
+
java: [/\bcatch\s*\(\w+\s+\w+\)/, /\bcatch\s*\(\s*Exception\b/],
|
|
192
|
+
rs: [/\.unwrap_or_else\s*\(/, /\bif\s+let\s+Err\b/],
|
|
193
|
+
cs: [/\bcatch\s*\(\w+\b/, /\bcatch\s*\{/],
|
|
194
|
+
rb: [/\brescue\b/],
|
|
195
|
+
};
|
|
196
|
+
export const MAX_RETRY_INDICATORS = [
|
|
197
|
+
/max.?retries?/i,
|
|
198
|
+
/retry.?count/i,
|
|
199
|
+
/retry.?limit/i,
|
|
200
|
+
/attempt/i,
|
|
201
|
+
/retries?\s*[<>=!]+\s*\d+/,
|
|
202
|
+
/count\s*[<>=!]+\s*\d+/,
|
|
203
|
+
/MAX_/,
|
|
204
|
+
/backoff/i,
|
|
205
|
+
/circuit.?breaker/i,
|
|
206
|
+
];
|
|
207
|
+
// ── File watcher patterns (circular trigger detection) ──
|
|
208
|
+
export const WATCHER_PATTERNS = {
|
|
209
|
+
js: [
|
|
210
|
+
/\bfs\.watch\s*\(/, /\bfs\.watchFile\s*\(/,
|
|
211
|
+
/\bchokidar\.watch\s*\(/, /\bnodemon\b/,
|
|
212
|
+
/\bnew\s+FSWatcher\b/,
|
|
213
|
+
],
|
|
214
|
+
ts: [
|
|
215
|
+
/\bfs\.watch\s*\(/, /\bfs\.watchFile\s*\(/,
|
|
216
|
+
/\bchokidar\.watch\s*\(/,
|
|
217
|
+
/\bnew\s+FSWatcher\b/,
|
|
218
|
+
],
|
|
219
|
+
py: [
|
|
220
|
+
/\bwatchdog\b/, /\bObserver\s*\(/,
|
|
221
|
+
/\binotify\b/, /\bwatchfiles\b/,
|
|
222
|
+
],
|
|
223
|
+
go: [
|
|
224
|
+
/\bfsnotify\.\w+/, /\bNewWatcher\s*\(/,
|
|
225
|
+
],
|
|
226
|
+
java: [
|
|
227
|
+
/\bWatchService\b/, /\bWatchKey\b/,
|
|
228
|
+
],
|
|
229
|
+
rs: [
|
|
230
|
+
/\bnotify::/, /\bRecommendedWatcher\b/,
|
|
231
|
+
],
|
|
232
|
+
cs: [
|
|
233
|
+
/\bFileSystemWatcher\b/, /\bnew\s+FileSystemWatcher\b/,
|
|
234
|
+
],
|
|
235
|
+
rb: [
|
|
236
|
+
/\bListen\.\w+/, /\brb-inotify\b/,
|
|
237
|
+
],
|
|
238
|
+
};
|
|
239
|
+
export const WRITE_PATTERNS = {
|
|
240
|
+
js: [/\bfs\.writeFile/, /\bfs\.appendFile/, /\bfs\.createWriteStream/, /\.write\s*\(/],
|
|
241
|
+
ts: [/\bfs\.writeFile/, /\bfs\.appendFile/, /\bfs\.createWriteStream/, /\.write\s*\(/],
|
|
242
|
+
py: [/\bopen\s*\([^)]*['"][wa]['"]/, /\.write\s*\(/, /\bshutil\.\w+/],
|
|
243
|
+
go: [/\bos\.WriteFile/, /\bos\.Create/, /\bio\.WriteString/, /\.Write\s*\(/],
|
|
244
|
+
java: [/\bFileWriter\b/, /\bBufferedWriter\b/, /\.write\s*\(/],
|
|
245
|
+
rs: [/\bfs::write/, /\bFile::create/, /\.write_all\s*\(/],
|
|
246
|
+
cs: [/\bFile\.Write/, /\bStreamWriter\b/, /\.Write\s*\(/],
|
|
247
|
+
rb: [/\bFile\.write/, /\bFile\.open\s*\([^)]*['"]w['"]/, /\.write\s*\(/],
|
|
248
|
+
};
|
|
249
|
+
// ── Resource lifecycle patterns (open without close) ──
|
|
250
|
+
export const RESOURCE_OPEN_PATTERNS = {
|
|
251
|
+
js: [/\bfs\.open\s*\(/, /\bfs\.createReadStream\s*\(/, /\bfs\.createWriteStream\s*\(/],
|
|
252
|
+
ts: [/\bfs\.open\s*\(/, /\bfs\.createReadStream\s*\(/, /\bfs\.createWriteStream\s*\(/],
|
|
253
|
+
py: [/\bopen\s*\(/],
|
|
254
|
+
go: [/\bos\.Open\s*\(/, /\bos\.Create\s*\(/, /\bos\.OpenFile\s*\(/],
|
|
255
|
+
java: [/\bnew\s+FileInputStream\b/, /\bnew\s+FileOutputStream\b/, /\bnew\s+BufferedReader\b/],
|
|
256
|
+
rs: [/\bFile::open\s*\(/, /\bFile::create\s*\(/],
|
|
257
|
+
cs: [/\bFile\.Open\s*\(/, /\bnew\s+FileStream\b/, /\bnew\s+StreamReader\b/],
|
|
258
|
+
rb: [/\bFile\.open\s*\(/],
|
|
259
|
+
};
|
|
260
|
+
export const RESOURCE_CLOSE_PATTERNS = {
|
|
261
|
+
js: [/\.close\s*\(/, /\.destroy\s*\(/, /\.end\s*\(/],
|
|
262
|
+
ts: [/\.close\s*\(/, /\.destroy\s*\(/, /\.end\s*\(/],
|
|
263
|
+
py: [/\.close\s*\(/, /\bwith\s+open\b/], // `with` auto-closes
|
|
264
|
+
go: [/\.Close\s*\(/, /\bdefer\b/], // defer auto-closes
|
|
265
|
+
java: [/\.close\s*\(/, /\btry\s*\(/], // try-with-resources
|
|
266
|
+
rs: [/\bdrop\s*\(/, /\}$/], // Rust auto-drops
|
|
267
|
+
cs: [/\.Close\s*\(/, /\.Dispose\s*\(/, /\busing\s*\(/], // using auto-disposes
|
|
268
|
+
rb: [/\.close\b/, /\bFile\.open\s*\([^)]*\)\s*do\b/], // block form auto-closes
|
|
269
|
+
};
|
|
270
|
+
// ── Auto-restart / self-respawn patterns ──
|
|
271
|
+
export const AUTO_RESTART_PATTERNS = {
|
|
272
|
+
js: [
|
|
273
|
+
/process\.on\s*\(\s*['"](?:exit|uncaughtException|SIGTERM)['"]\s*,\s*(?:function|\(|=>).*(?:spawn|exec|fork)/,
|
|
274
|
+
/process\.on\s*\(\s*['"]exit['"]/,
|
|
275
|
+
],
|
|
276
|
+
ts: [
|
|
277
|
+
/process\.on\s*\(\s*['"](?:exit|uncaughtException|SIGTERM)['"]\s*,\s*(?:function|\(|=>).*(?:spawn|exec|fork)/,
|
|
278
|
+
/process\.on\s*\(\s*['"]exit['"]/,
|
|
279
|
+
],
|
|
280
|
+
py: [
|
|
281
|
+
/\batexit\.register\s*\(/,
|
|
282
|
+
/\bsignal\.signal\s*\(\s*signal\.SIG\w+\s*,/,
|
|
283
|
+
],
|
|
284
|
+
go: [
|
|
285
|
+
/\bsignal\.Notify\s*\(/,
|
|
286
|
+
/\bos\.Exit\s*\(/,
|
|
287
|
+
],
|
|
288
|
+
java: [
|
|
289
|
+
/\bRuntime\.getRuntime\(\)\.addShutdownHook\b/,
|
|
290
|
+
],
|
|
291
|
+
rs: [
|
|
292
|
+
/\bctrlc::set_handler\b/,
|
|
293
|
+
/\bsignal::ctrl_c\b/,
|
|
294
|
+
],
|
|
295
|
+
cs: [
|
|
296
|
+
/\bAppDomain\.CurrentDomain\.ProcessExit\b/,
|
|
297
|
+
],
|
|
298
|
+
rb: [
|
|
299
|
+
/\bat_exit\b/,
|
|
300
|
+
/\btrap\s*\(/,
|
|
301
|
+
],
|
|
302
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export * from './templates/index.js';
|
|
|
6
6
|
export * from './types/fix-packet.js';
|
|
7
7
|
export { Gate, GateContext } from './gates/base.js';
|
|
8
8
|
export { RetryLoopBreakerGate } from './gates/retry-loop-breaker.js';
|
|
9
|
+
export { SideEffectAnalysisGate } from './gates/side-effect-analysis.js';
|
|
9
10
|
export * from './utils/logger.js';
|
|
10
11
|
export * from './services/score-history.js';
|
|
11
12
|
export * from './hooks/index.js';
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export * from './templates/index.js';
|
|
|
6
6
|
export * from './types/fix-packet.js';
|
|
7
7
|
export { Gate } from './gates/base.js';
|
|
8
8
|
export { RetryLoopBreakerGate } from './gates/retry-loop-breaker.js';
|
|
9
|
+
export { SideEffectAnalysisGate } from './gates/side-effect-analysis.js';
|
|
9
10
|
export * from './utils/logger.js';
|
|
10
11
|
export * from './services/score-history.js';
|
|
11
12
|
export * from './hooks/index.js';
|
|
@@ -187,6 +187,18 @@ export const UNIVERSAL_CONFIG = {
|
|
|
187
187
|
ignore_patterns: [],
|
|
188
188
|
audit_log: true,
|
|
189
189
|
},
|
|
190
|
+
side_effect_analysis: {
|
|
191
|
+
enabled: true,
|
|
192
|
+
check_unbounded_timers: true,
|
|
193
|
+
check_unbounded_loops: true,
|
|
194
|
+
check_process_lifecycle: true,
|
|
195
|
+
check_recursive_depth: true,
|
|
196
|
+
check_resource_lifecycle: true,
|
|
197
|
+
check_retry_without_limit: true,
|
|
198
|
+
check_circular_triggers: true,
|
|
199
|
+
check_auto_restart: true,
|
|
200
|
+
ignore_patterns: [],
|
|
201
|
+
},
|
|
190
202
|
deep: {
|
|
191
203
|
enabled: false,
|
|
192
204
|
pro: false,
|
package/dist/types/index.d.ts
CHANGED
|
@@ -452,6 +452,40 @@ export declare const GatesSchema: z.ZodObject<{
|
|
|
452
452
|
custom_patterns?: string[] | undefined;
|
|
453
453
|
audit_log?: boolean | undefined;
|
|
454
454
|
}>>>;
|
|
455
|
+
side_effect_analysis: z.ZodDefault<z.ZodOptional<z.ZodObject<{
|
|
456
|
+
enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
457
|
+
check_unbounded_timers: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
458
|
+
check_unbounded_loops: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
459
|
+
check_process_lifecycle: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
460
|
+
check_recursive_depth: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
461
|
+
check_resource_lifecycle: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
462
|
+
check_retry_without_limit: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
463
|
+
check_circular_triggers: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
464
|
+
check_auto_restart: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
465
|
+
ignore_patterns: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
|
|
466
|
+
}, "strip", z.ZodTypeAny, {
|
|
467
|
+
enabled: boolean;
|
|
468
|
+
ignore_patterns: string[];
|
|
469
|
+
check_unbounded_timers: boolean;
|
|
470
|
+
check_unbounded_loops: boolean;
|
|
471
|
+
check_process_lifecycle: boolean;
|
|
472
|
+
check_recursive_depth: boolean;
|
|
473
|
+
check_resource_lifecycle: boolean;
|
|
474
|
+
check_retry_without_limit: boolean;
|
|
475
|
+
check_circular_triggers: boolean;
|
|
476
|
+
check_auto_restart: boolean;
|
|
477
|
+
}, {
|
|
478
|
+
enabled?: boolean | undefined;
|
|
479
|
+
ignore_patterns?: string[] | undefined;
|
|
480
|
+
check_unbounded_timers?: boolean | undefined;
|
|
481
|
+
check_unbounded_loops?: boolean | undefined;
|
|
482
|
+
check_process_lifecycle?: boolean | undefined;
|
|
483
|
+
check_recursive_depth?: boolean | undefined;
|
|
484
|
+
check_resource_lifecycle?: boolean | undefined;
|
|
485
|
+
check_retry_without_limit?: boolean | undefined;
|
|
486
|
+
check_circular_triggers?: boolean | undefined;
|
|
487
|
+
check_auto_restart?: boolean | undefined;
|
|
488
|
+
}>>>;
|
|
455
489
|
deep: z.ZodDefault<z.ZodOptional<z.ZodObject<{
|
|
456
490
|
enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
457
491
|
pro: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
@@ -725,6 +759,18 @@ export declare const GatesSchema: z.ZodObject<{
|
|
|
725
759
|
custom_patterns: string[];
|
|
726
760
|
audit_log: boolean;
|
|
727
761
|
};
|
|
762
|
+
side_effect_analysis: {
|
|
763
|
+
enabled: boolean;
|
|
764
|
+
ignore_patterns: string[];
|
|
765
|
+
check_unbounded_timers: boolean;
|
|
766
|
+
check_unbounded_loops: boolean;
|
|
767
|
+
check_process_lifecycle: boolean;
|
|
768
|
+
check_recursive_depth: boolean;
|
|
769
|
+
check_resource_lifecycle: boolean;
|
|
770
|
+
check_retry_without_limit: boolean;
|
|
771
|
+
check_circular_triggers: boolean;
|
|
772
|
+
check_auto_restart: boolean;
|
|
773
|
+
};
|
|
728
774
|
}, {
|
|
729
775
|
deep?: {
|
|
730
776
|
enabled?: boolean | undefined;
|
|
@@ -913,6 +959,18 @@ export declare const GatesSchema: z.ZodObject<{
|
|
|
913
959
|
custom_patterns?: string[] | undefined;
|
|
914
960
|
audit_log?: boolean | undefined;
|
|
915
961
|
} | undefined;
|
|
962
|
+
side_effect_analysis?: {
|
|
963
|
+
enabled?: boolean | undefined;
|
|
964
|
+
ignore_patterns?: string[] | undefined;
|
|
965
|
+
check_unbounded_timers?: boolean | undefined;
|
|
966
|
+
check_unbounded_loops?: boolean | undefined;
|
|
967
|
+
check_process_lifecycle?: boolean | undefined;
|
|
968
|
+
check_recursive_depth?: boolean | undefined;
|
|
969
|
+
check_resource_lifecycle?: boolean | undefined;
|
|
970
|
+
check_retry_without_limit?: boolean | undefined;
|
|
971
|
+
check_circular_triggers?: boolean | undefined;
|
|
972
|
+
check_auto_restart?: boolean | undefined;
|
|
973
|
+
} | undefined;
|
|
916
974
|
}>;
|
|
917
975
|
export declare const CommandsSchema: z.ZodObject<{
|
|
918
976
|
format: z.ZodOptional<z.ZodString>;
|
|
@@ -1426,6 +1484,40 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
1426
1484
|
custom_patterns?: string[] | undefined;
|
|
1427
1485
|
audit_log?: boolean | undefined;
|
|
1428
1486
|
}>>>;
|
|
1487
|
+
side_effect_analysis: z.ZodDefault<z.ZodOptional<z.ZodObject<{
|
|
1488
|
+
enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
1489
|
+
check_unbounded_timers: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
1490
|
+
check_unbounded_loops: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
1491
|
+
check_process_lifecycle: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
1492
|
+
check_recursive_depth: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
1493
|
+
check_resource_lifecycle: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
1494
|
+
check_retry_without_limit: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
1495
|
+
check_circular_triggers: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
1496
|
+
check_auto_restart: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
1497
|
+
ignore_patterns: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
|
|
1498
|
+
}, "strip", z.ZodTypeAny, {
|
|
1499
|
+
enabled: boolean;
|
|
1500
|
+
ignore_patterns: string[];
|
|
1501
|
+
check_unbounded_timers: boolean;
|
|
1502
|
+
check_unbounded_loops: boolean;
|
|
1503
|
+
check_process_lifecycle: boolean;
|
|
1504
|
+
check_recursive_depth: boolean;
|
|
1505
|
+
check_resource_lifecycle: boolean;
|
|
1506
|
+
check_retry_without_limit: boolean;
|
|
1507
|
+
check_circular_triggers: boolean;
|
|
1508
|
+
check_auto_restart: boolean;
|
|
1509
|
+
}, {
|
|
1510
|
+
enabled?: boolean | undefined;
|
|
1511
|
+
ignore_patterns?: string[] | undefined;
|
|
1512
|
+
check_unbounded_timers?: boolean | undefined;
|
|
1513
|
+
check_unbounded_loops?: boolean | undefined;
|
|
1514
|
+
check_process_lifecycle?: boolean | undefined;
|
|
1515
|
+
check_recursive_depth?: boolean | undefined;
|
|
1516
|
+
check_resource_lifecycle?: boolean | undefined;
|
|
1517
|
+
check_retry_without_limit?: boolean | undefined;
|
|
1518
|
+
check_circular_triggers?: boolean | undefined;
|
|
1519
|
+
check_auto_restart?: boolean | undefined;
|
|
1520
|
+
}>>>;
|
|
1429
1521
|
deep: z.ZodDefault<z.ZodOptional<z.ZodObject<{
|
|
1430
1522
|
enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
1431
1523
|
pro: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
@@ -1699,6 +1791,18 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
1699
1791
|
custom_patterns: string[];
|
|
1700
1792
|
audit_log: boolean;
|
|
1701
1793
|
};
|
|
1794
|
+
side_effect_analysis: {
|
|
1795
|
+
enabled: boolean;
|
|
1796
|
+
ignore_patterns: string[];
|
|
1797
|
+
check_unbounded_timers: boolean;
|
|
1798
|
+
check_unbounded_loops: boolean;
|
|
1799
|
+
check_process_lifecycle: boolean;
|
|
1800
|
+
check_recursive_depth: boolean;
|
|
1801
|
+
check_resource_lifecycle: boolean;
|
|
1802
|
+
check_retry_without_limit: boolean;
|
|
1803
|
+
check_circular_triggers: boolean;
|
|
1804
|
+
check_auto_restart: boolean;
|
|
1805
|
+
};
|
|
1702
1806
|
}, {
|
|
1703
1807
|
deep?: {
|
|
1704
1808
|
enabled?: boolean | undefined;
|
|
@@ -1887,6 +1991,18 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
1887
1991
|
custom_patterns?: string[] | undefined;
|
|
1888
1992
|
audit_log?: boolean | undefined;
|
|
1889
1993
|
} | undefined;
|
|
1994
|
+
side_effect_analysis?: {
|
|
1995
|
+
enabled?: boolean | undefined;
|
|
1996
|
+
ignore_patterns?: string[] | undefined;
|
|
1997
|
+
check_unbounded_timers?: boolean | undefined;
|
|
1998
|
+
check_unbounded_loops?: boolean | undefined;
|
|
1999
|
+
check_process_lifecycle?: boolean | undefined;
|
|
2000
|
+
check_recursive_depth?: boolean | undefined;
|
|
2001
|
+
check_resource_lifecycle?: boolean | undefined;
|
|
2002
|
+
check_retry_without_limit?: boolean | undefined;
|
|
2003
|
+
check_circular_triggers?: boolean | undefined;
|
|
2004
|
+
check_auto_restart?: boolean | undefined;
|
|
2005
|
+
} | undefined;
|
|
1890
2006
|
}>>>;
|
|
1891
2007
|
hooks: z.ZodDefault<z.ZodOptional<z.ZodObject<{
|
|
1892
2008
|
enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
@@ -2117,6 +2233,18 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
2117
2233
|
custom_patterns: string[];
|
|
2118
2234
|
audit_log: boolean;
|
|
2119
2235
|
};
|
|
2236
|
+
side_effect_analysis: {
|
|
2237
|
+
enabled: boolean;
|
|
2238
|
+
ignore_patterns: string[];
|
|
2239
|
+
check_unbounded_timers: boolean;
|
|
2240
|
+
check_unbounded_loops: boolean;
|
|
2241
|
+
check_process_lifecycle: boolean;
|
|
2242
|
+
check_recursive_depth: boolean;
|
|
2243
|
+
check_resource_lifecycle: boolean;
|
|
2244
|
+
check_retry_without_limit: boolean;
|
|
2245
|
+
check_circular_triggers: boolean;
|
|
2246
|
+
check_auto_restart: boolean;
|
|
2247
|
+
};
|
|
2120
2248
|
};
|
|
2121
2249
|
hooks: {
|
|
2122
2250
|
enabled: boolean;
|
|
@@ -2331,6 +2459,18 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
2331
2459
|
custom_patterns?: string[] | undefined;
|
|
2332
2460
|
audit_log?: boolean | undefined;
|
|
2333
2461
|
} | undefined;
|
|
2462
|
+
side_effect_analysis?: {
|
|
2463
|
+
enabled?: boolean | undefined;
|
|
2464
|
+
ignore_patterns?: string[] | undefined;
|
|
2465
|
+
check_unbounded_timers?: boolean | undefined;
|
|
2466
|
+
check_unbounded_loops?: boolean | undefined;
|
|
2467
|
+
check_process_lifecycle?: boolean | undefined;
|
|
2468
|
+
check_recursive_depth?: boolean | undefined;
|
|
2469
|
+
check_resource_lifecycle?: boolean | undefined;
|
|
2470
|
+
check_retry_without_limit?: boolean | undefined;
|
|
2471
|
+
check_circular_triggers?: boolean | undefined;
|
|
2472
|
+
check_auto_restart?: boolean | undefined;
|
|
2473
|
+
} | undefined;
|
|
2334
2474
|
} | undefined;
|
|
2335
2475
|
hooks?: {
|
|
2336
2476
|
enabled?: boolean | undefined;
|
package/dist/types/index.js
CHANGED
|
@@ -225,6 +225,19 @@ export const GatesSchema = z.object({
|
|
|
225
225
|
ignore_patterns: z.array(z.string()).optional().default([]),
|
|
226
226
|
audit_log: z.boolean().optional().default(true),
|
|
227
227
|
}).optional().default({}),
|
|
228
|
+
// v4.3+ Side-Effect Safety Analysis
|
|
229
|
+
side_effect_analysis: z.object({
|
|
230
|
+
enabled: z.boolean().optional().default(true),
|
|
231
|
+
check_unbounded_timers: z.boolean().optional().default(true),
|
|
232
|
+
check_unbounded_loops: z.boolean().optional().default(true),
|
|
233
|
+
check_process_lifecycle: z.boolean().optional().default(true),
|
|
234
|
+
check_recursive_depth: z.boolean().optional().default(true),
|
|
235
|
+
check_resource_lifecycle: z.boolean().optional().default(true),
|
|
236
|
+
check_retry_without_limit: z.boolean().optional().default(true),
|
|
237
|
+
check_circular_triggers: z.boolean().optional().default(true),
|
|
238
|
+
check_auto_restart: z.boolean().optional().default(true),
|
|
239
|
+
ignore_patterns: z.array(z.string()).optional().default([]),
|
|
240
|
+
}).optional().default({}),
|
|
228
241
|
// v4.0+ Deep Analysis (LLM-powered)
|
|
229
242
|
deep: z.object({
|
|
230
243
|
enabled: z.boolean().optional().default(false),
|
|
@@ -265,6 +278,7 @@ export const HooksSchema = z.object({
|
|
|
265
278
|
'deprecated-apis',
|
|
266
279
|
'promise-safety',
|
|
267
280
|
'security-patterns',
|
|
281
|
+
'side-effect-analysis',
|
|
268
282
|
'file-size',
|
|
269
283
|
]),
|
|
270
284
|
timeout_ms: z.number().optional().default(5000),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rigour-labs/core",
|
|
3
|
-
"version": "4.3.
|
|
3
|
+
"version": "4.3.1",
|
|
4
4
|
"description": "Deterministic quality gate engine for AI-generated code. AST analysis, drift detection, and Fix Packet generation across TypeScript, JavaScript, Python, Go, Ruby, and C#.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://rigour.run",
|
|
@@ -59,11 +59,11 @@
|
|
|
59
59
|
"@xenova/transformers": "^2.17.2",
|
|
60
60
|
"better-sqlite3": "^11.0.0",
|
|
61
61
|
"openai": "^4.104.0",
|
|
62
|
-
"@rigour-labs/brain-
|
|
63
|
-
"@rigour-labs/brain-
|
|
64
|
-
"@rigour-labs/brain-
|
|
65
|
-
"@rigour-labs/brain-win-x64": "4.3.
|
|
66
|
-
"@rigour-labs/brain-
|
|
62
|
+
"@rigour-labs/brain-darwin-arm64": "4.3.1",
|
|
63
|
+
"@rigour-labs/brain-darwin-x64": "4.3.1",
|
|
64
|
+
"@rigour-labs/brain-linux-arm64": "4.3.1",
|
|
65
|
+
"@rigour-labs/brain-win-x64": "4.3.1",
|
|
66
|
+
"@rigour-labs/brain-linux-x64": "4.3.1"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"@types/better-sqlite3": "^7.6.12",
|