@rigour-labs/core 2.22.0 → 3.0.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/README.md +58 -0
- package/dist/context.test.js +2 -3
- package/dist/environment.test.js +2 -1
- package/dist/gates/agent-team.d.ts +2 -1
- package/dist/gates/agent-team.js +1 -0
- package/dist/gates/base.d.ts +3 -1
- package/dist/gates/base.js +3 -0
- package/dist/gates/checkpoint.d.ts +2 -1
- package/dist/gates/checkpoint.js +3 -2
- package/dist/gates/context-window-artifacts.d.ts +2 -1
- package/dist/gates/context-window-artifacts.js +6 -3
- package/dist/gates/context.d.ts +2 -1
- package/dist/gates/context.js +1 -0
- package/dist/gates/coverage.js +3 -1
- package/dist/gates/dependency.js +5 -5
- package/dist/gates/duplication-drift.d.ts +2 -1
- package/dist/gates/duplication-drift.js +4 -1
- package/dist/gates/environment.js +4 -4
- package/dist/gates/hallucinated-imports.d.ts +21 -2
- package/dist/gates/hallucinated-imports.js +116 -2
- package/dist/gates/inconsistent-error-handling.d.ts +2 -1
- package/dist/gates/inconsistent-error-handling.js +21 -7
- package/dist/gates/promise-safety.d.ts +68 -0
- package/dist/gates/promise-safety.js +509 -0
- package/dist/gates/retry-loop-breaker.d.ts +2 -1
- package/dist/gates/retry-loop-breaker.js +2 -1
- package/dist/gates/runner.js +34 -1
- package/dist/gates/safety.d.ts +2 -1
- package/dist/gates/safety.js +2 -1
- package/dist/gates/security-patterns.d.ts +2 -1
- package/dist/gates/security-patterns.js +1 -0
- package/dist/gates/structure.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/services/fix-packet-service.d.ts +0 -1
- package/dist/services/fix-packet-service.js +9 -14
- package/dist/services/score-history.d.ts +54 -0
- package/dist/services/score-history.js +122 -0
- package/dist/templates/index.js +169 -0
- package/dist/types/fix-packet.d.ts +5 -5
- package/dist/types/fix-packet.js +1 -1
- package/dist/types/index.d.ts +153 -0
- package/dist/types/index.js +19 -0
- package/package.json +21 -1
- package/src/context.test.ts +0 -256
- package/src/discovery.test.ts +0 -88
- package/src/discovery.ts +0 -112
- package/src/environment.test.ts +0 -115
- package/src/gates/agent-team.test.ts +0 -134
- package/src/gates/agent-team.ts +0 -210
- package/src/gates/ast-handlers/base.ts +0 -13
- package/src/gates/ast-handlers/python.ts +0 -145
- package/src/gates/ast-handlers/python_parser.py +0 -181
- package/src/gates/ast-handlers/typescript.ts +0 -264
- package/src/gates/ast-handlers/universal.ts +0 -184
- package/src/gates/ast.ts +0 -54
- package/src/gates/base.ts +0 -28
- package/src/gates/checkpoint.test.ts +0 -135
- package/src/gates/checkpoint.ts +0 -311
- package/src/gates/content.ts +0 -51
- package/src/gates/context-window-artifacts.ts +0 -277
- package/src/gates/context.ts +0 -270
- package/src/gates/coverage.ts +0 -74
- package/src/gates/dependency.ts +0 -108
- package/src/gates/duplication-drift.ts +0 -231
- package/src/gates/environment.ts +0 -94
- package/src/gates/file.ts +0 -46
- package/src/gates/hallucinated-imports.ts +0 -361
- package/src/gates/inconsistent-error-handling.ts +0 -254
- package/src/gates/retry-loop-breaker.ts +0 -151
- package/src/gates/runner.ts +0 -188
- package/src/gates/safety.ts +0 -56
- package/src/gates/security-patterns.test.ts +0 -162
- package/src/gates/security-patterns.ts +0 -306
- package/src/gates/structure.ts +0 -36
- package/src/index.ts +0 -13
- package/src/pattern-index/embeddings.ts +0 -84
- package/src/pattern-index/index.ts +0 -59
- package/src/pattern-index/indexer.test.ts +0 -276
- package/src/pattern-index/indexer.ts +0 -1023
- package/src/pattern-index/matcher.test.ts +0 -293
- package/src/pattern-index/matcher.ts +0 -493
- package/src/pattern-index/overrides.ts +0 -235
- package/src/pattern-index/security.ts +0 -151
- package/src/pattern-index/staleness.test.ts +0 -313
- package/src/pattern-index/staleness.ts +0 -568
- package/src/pattern-index/types.ts +0 -339
- package/src/safety.test.ts +0 -53
- package/src/services/adaptive-thresholds.test.ts +0 -189
- package/src/services/adaptive-thresholds.ts +0 -275
- package/src/services/context-engine.ts +0 -104
- package/src/services/fix-packet-service.ts +0 -42
- package/src/services/state-service.ts +0 -138
- package/src/smoke.test.ts +0 -18
- package/src/templates/index.ts +0 -338
- package/src/types/fix-packet.ts +0 -32
- package/src/types/index.ts +0 -200
- package/src/utils/logger.ts +0 -43
- package/src/utils/scanner.test.ts +0 -37
- package/src/utils/scanner.ts +0 -43
- package/tsconfig.json +0 -10
- package/vitest.config.ts +0 -7
- package/vitest.setup.ts +0 -30
package/src/templates/index.ts
DELETED
|
@@ -1,338 +0,0 @@
|
|
|
1
|
-
import { Config, Commands, Gates } from '../types/index.js';
|
|
2
|
-
|
|
3
|
-
export interface Template {
|
|
4
|
-
name: string;
|
|
5
|
-
markers: string[];
|
|
6
|
-
config: {
|
|
7
|
-
preset?: string;
|
|
8
|
-
paradigm?: string;
|
|
9
|
-
commands?: Partial<Commands>;
|
|
10
|
-
gates?: Partial<Gates>;
|
|
11
|
-
planned?: string[];
|
|
12
|
-
ignore?: string[];
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const TEMPLATES: Template[] = [
|
|
17
|
-
{
|
|
18
|
-
name: 'ui',
|
|
19
|
-
markers: [
|
|
20
|
-
'react',
|
|
21
|
-
'next',
|
|
22
|
-
'vue',
|
|
23
|
-
'svelte',
|
|
24
|
-
'next.config.js',
|
|
25
|
-
'vite.config.ts',
|
|
26
|
-
'tailwind.config.js',
|
|
27
|
-
'base.css',
|
|
28
|
-
'index.html',
|
|
29
|
-
],
|
|
30
|
-
config: {
|
|
31
|
-
preset: 'ui',
|
|
32
|
-
ignore: [
|
|
33
|
-
'.git/**',
|
|
34
|
-
'node_modules/**',
|
|
35
|
-
'dist/**',
|
|
36
|
-
'build/**',
|
|
37
|
-
'.next/**',
|
|
38
|
-
'.nuxt/**',
|
|
39
|
-
'.svelte-kit/**',
|
|
40
|
-
'coverage/**',
|
|
41
|
-
'.turbo/**',
|
|
42
|
-
],
|
|
43
|
-
gates: {
|
|
44
|
-
max_file_lines: 300,
|
|
45
|
-
required_files: ['docs/SPEC.md', 'docs/ARCH.md', 'README.md'],
|
|
46
|
-
},
|
|
47
|
-
planned: [
|
|
48
|
-
'Layer Boundary: Components cannot import from DB',
|
|
49
|
-
'Prop-Drilling Detection: Max depth 5',
|
|
50
|
-
],
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
name: 'api',
|
|
55
|
-
markers: [
|
|
56
|
-
'express',
|
|
57
|
-
'fastify',
|
|
58
|
-
'nestjs',
|
|
59
|
-
'go.mod',
|
|
60
|
-
'requirements.txt',
|
|
61
|
-
'pyproject.toml',
|
|
62
|
-
'app.py',
|
|
63
|
-
'main.go',
|
|
64
|
-
'index.js',
|
|
65
|
-
],
|
|
66
|
-
config: {
|
|
67
|
-
preset: 'api',
|
|
68
|
-
ignore: [
|
|
69
|
-
'.git/**',
|
|
70
|
-
// Node.js
|
|
71
|
-
'node_modules/**',
|
|
72
|
-
'dist/**',
|
|
73
|
-
// Python
|
|
74
|
-
'venv/**',
|
|
75
|
-
'.venv/**',
|
|
76
|
-
'__pycache__/**',
|
|
77
|
-
'*.pyc',
|
|
78
|
-
'.tox/**',
|
|
79
|
-
'.pytest_cache/**',
|
|
80
|
-
'.mypy_cache/**',
|
|
81
|
-
'*.egg-info/**',
|
|
82
|
-
// Go
|
|
83
|
-
'vendor/**',
|
|
84
|
-
],
|
|
85
|
-
gates: {
|
|
86
|
-
max_file_lines: 400,
|
|
87
|
-
required_files: ['docs/SPEC.md', 'docs/ARCH.md', 'README.md'],
|
|
88
|
-
},
|
|
89
|
-
planned: [
|
|
90
|
-
'Service Layer Enforcement: Controllers -> Services only',
|
|
91
|
-
'Repo Pattern: Databases access isolated to repositories/',
|
|
92
|
-
],
|
|
93
|
-
},
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
name: 'infra',
|
|
97
|
-
markers: [
|
|
98
|
-
'Dockerfile',
|
|
99
|
-
'docker-compose.yml',
|
|
100
|
-
'main.tf',
|
|
101
|
-
'k8s/',
|
|
102
|
-
'helm/',
|
|
103
|
-
'ansible/',
|
|
104
|
-
],
|
|
105
|
-
config: {
|
|
106
|
-
preset: 'infra',
|
|
107
|
-
ignore: [
|
|
108
|
-
'.git/**',
|
|
109
|
-
'.terraform/**',
|
|
110
|
-
'*.tfstate',
|
|
111
|
-
'*.tfstate.backup',
|
|
112
|
-
'.terragrunt-cache/**',
|
|
113
|
-
'charts/**/*.tgz',
|
|
114
|
-
],
|
|
115
|
-
gates: {
|
|
116
|
-
max_file_lines: 300,
|
|
117
|
-
required_files: ['docs/RUNBOOK.md', 'docs/ARCH.md', 'README.md'],
|
|
118
|
-
},
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
name: 'data',
|
|
123
|
-
markers: [
|
|
124
|
-
'ipynb',
|
|
125
|
-
'spark',
|
|
126
|
-
'pandas',
|
|
127
|
-
'data/',
|
|
128
|
-
'dbt_project.yml',
|
|
129
|
-
],
|
|
130
|
-
config: {
|
|
131
|
-
preset: 'data',
|
|
132
|
-
ignore: [
|
|
133
|
-
'.git/**',
|
|
134
|
-
'.ipynb_checkpoints/**',
|
|
135
|
-
'__pycache__/**',
|
|
136
|
-
'*.pyc',
|
|
137
|
-
'dbt_packages/**',
|
|
138
|
-
'target/**',
|
|
139
|
-
'logs/**',
|
|
140
|
-
'*.parquet',
|
|
141
|
-
'*.csv',
|
|
142
|
-
],
|
|
143
|
-
gates: {
|
|
144
|
-
max_file_lines: 500,
|
|
145
|
-
required_files: ['docs/DATA_DICTIONARY.md', 'docs/PIPELINE.md', 'README.md'],
|
|
146
|
-
},
|
|
147
|
-
planned: [
|
|
148
|
-
'Stochastic Determinism: Seed setting enforcement',
|
|
149
|
-
'Data Leaks: Detecting PII in notebook outputs',
|
|
150
|
-
],
|
|
151
|
-
},
|
|
152
|
-
},
|
|
153
|
-
];
|
|
154
|
-
|
|
155
|
-
export const PARADIGM_TEMPLATES: Template[] = [
|
|
156
|
-
{
|
|
157
|
-
name: 'oop',
|
|
158
|
-
markers: [
|
|
159
|
-
'class ',
|
|
160
|
-
'interface ',
|
|
161
|
-
'implements ',
|
|
162
|
-
'extends ',
|
|
163
|
-
'constructor(',
|
|
164
|
-
'private ',
|
|
165
|
-
'public ',
|
|
166
|
-
'protected ',
|
|
167
|
-
],
|
|
168
|
-
config: {
|
|
169
|
-
paradigm: 'oop',
|
|
170
|
-
gates: {
|
|
171
|
-
max_file_lines: 400,
|
|
172
|
-
ast: {
|
|
173
|
-
complexity: 10,
|
|
174
|
-
max_methods: 10,
|
|
175
|
-
max_params: 5,
|
|
176
|
-
max_nesting: 4,
|
|
177
|
-
max_inheritance_depth: 3,
|
|
178
|
-
max_class_dependencies: 5,
|
|
179
|
-
max_function_lines: 60,
|
|
180
|
-
},
|
|
181
|
-
},
|
|
182
|
-
},
|
|
183
|
-
},
|
|
184
|
-
{
|
|
185
|
-
name: 'functional',
|
|
186
|
-
// Removed '=>' as primary marker - too broad (appears in OOP callbacks)
|
|
187
|
-
markers: [
|
|
188
|
-
'export const',
|
|
189
|
-
'reduce(',
|
|
190
|
-
'.pipe(',
|
|
191
|
-
'compose(',
|
|
192
|
-
'curry(',
|
|
193
|
-
'readonly ',
|
|
194
|
-
],
|
|
195
|
-
config: {
|
|
196
|
-
paradigm: 'functional',
|
|
197
|
-
gates: {
|
|
198
|
-
max_file_lines: 350,
|
|
199
|
-
ast: {
|
|
200
|
-
complexity: 8,
|
|
201
|
-
max_methods: 15, // Functions, not classes
|
|
202
|
-
max_params: 4,
|
|
203
|
-
max_nesting: 3,
|
|
204
|
-
max_inheritance_depth: 3,
|
|
205
|
-
max_class_dependencies: 5,
|
|
206
|
-
max_function_lines: 40,
|
|
207
|
-
},
|
|
208
|
-
},
|
|
209
|
-
},
|
|
210
|
-
},
|
|
211
|
-
];
|
|
212
|
-
|
|
213
|
-
export const UNIVERSAL_CONFIG: Config = {
|
|
214
|
-
version: 1,
|
|
215
|
-
commands: {},
|
|
216
|
-
gates: {
|
|
217
|
-
max_file_lines: 500,
|
|
218
|
-
forbid_todos: true,
|
|
219
|
-
forbid_fixme: true,
|
|
220
|
-
forbid_paths: [],
|
|
221
|
-
required_files: ['docs/SPEC.md', 'docs/ARCH.md', 'docs/DECISIONS.md', 'docs/TASKS.md'],
|
|
222
|
-
ast: {
|
|
223
|
-
complexity: 10,
|
|
224
|
-
max_methods: 10,
|
|
225
|
-
max_params: 5,
|
|
226
|
-
max_nesting: 4,
|
|
227
|
-
max_inheritance_depth: 3,
|
|
228
|
-
max_class_dependencies: 5,
|
|
229
|
-
max_function_lines: 50,
|
|
230
|
-
},
|
|
231
|
-
dependencies: {
|
|
232
|
-
forbid: [],
|
|
233
|
-
},
|
|
234
|
-
architecture: {
|
|
235
|
-
boundaries: [],
|
|
236
|
-
},
|
|
237
|
-
safety: {
|
|
238
|
-
max_files_changed_per_cycle: 10,
|
|
239
|
-
protected_paths: ['.github/**', 'docs/**', 'rigour.yml'],
|
|
240
|
-
},
|
|
241
|
-
context: {
|
|
242
|
-
enabled: true,
|
|
243
|
-
sensitivity: 0.8,
|
|
244
|
-
mining_depth: 100,
|
|
245
|
-
ignored_patterns: [],
|
|
246
|
-
cross_file_patterns: true,
|
|
247
|
-
naming_consistency: true,
|
|
248
|
-
import_relationships: true,
|
|
249
|
-
max_cross_file_depth: 50,
|
|
250
|
-
},
|
|
251
|
-
environment: {
|
|
252
|
-
enabled: true,
|
|
253
|
-
enforce_contracts: true,
|
|
254
|
-
tools: {},
|
|
255
|
-
required_env: [],
|
|
256
|
-
},
|
|
257
|
-
retry_loop_breaker: {
|
|
258
|
-
enabled: true,
|
|
259
|
-
max_retries: 3,
|
|
260
|
-
auto_classify: true,
|
|
261
|
-
doc_sources: {},
|
|
262
|
-
},
|
|
263
|
-
agent_team: {
|
|
264
|
-
enabled: false,
|
|
265
|
-
max_concurrent_agents: 3,
|
|
266
|
-
cross_agent_pattern_check: true,
|
|
267
|
-
handoff_verification: true,
|
|
268
|
-
task_ownership: 'strict',
|
|
269
|
-
},
|
|
270
|
-
checkpoint: {
|
|
271
|
-
enabled: false,
|
|
272
|
-
interval_minutes: 15,
|
|
273
|
-
quality_threshold: 80,
|
|
274
|
-
drift_detection: true,
|
|
275
|
-
auto_save_on_failure: true,
|
|
276
|
-
},
|
|
277
|
-
security: {
|
|
278
|
-
enabled: true,
|
|
279
|
-
sql_injection: true,
|
|
280
|
-
xss: true,
|
|
281
|
-
path_traversal: true,
|
|
282
|
-
hardcoded_secrets: true,
|
|
283
|
-
insecure_randomness: true,
|
|
284
|
-
command_injection: true,
|
|
285
|
-
block_on_severity: 'high',
|
|
286
|
-
},
|
|
287
|
-
adaptive: {
|
|
288
|
-
enabled: false,
|
|
289
|
-
base_coverage_threshold: 80,
|
|
290
|
-
base_quality_threshold: 80,
|
|
291
|
-
auto_detect_tier: true,
|
|
292
|
-
},
|
|
293
|
-
staleness: {
|
|
294
|
-
enabled: false,
|
|
295
|
-
rules: {
|
|
296
|
-
'no-var': true,
|
|
297
|
-
'no-commonjs': false,
|
|
298
|
-
'no-arguments': false,
|
|
299
|
-
'prefer-arrow': false,
|
|
300
|
-
'prefer-template': false,
|
|
301
|
-
'prefer-spread': false,
|
|
302
|
-
'prefer-rest': false,
|
|
303
|
-
'prefer-const': false,
|
|
304
|
-
},
|
|
305
|
-
},
|
|
306
|
-
duplication_drift: {
|
|
307
|
-
enabled: true,
|
|
308
|
-
similarity_threshold: 0.8,
|
|
309
|
-
min_body_lines: 5,
|
|
310
|
-
},
|
|
311
|
-
hallucinated_imports: {
|
|
312
|
-
enabled: true,
|
|
313
|
-
check_relative: true,
|
|
314
|
-
check_packages: true,
|
|
315
|
-
ignore_patterns: [
|
|
316
|
-
'\\.css$', '\\.scss$', '\\.less$', '\\.svg$', '\\.png$', '\\.jpg$',
|
|
317
|
-
'\\.json$', '\\.wasm$', '\\.graphql$', '\\.gql$',
|
|
318
|
-
],
|
|
319
|
-
},
|
|
320
|
-
inconsistent_error_handling: {
|
|
321
|
-
enabled: true,
|
|
322
|
-
max_strategies_per_type: 2,
|
|
323
|
-
min_occurrences: 3,
|
|
324
|
-
ignore_empty_catches: false,
|
|
325
|
-
},
|
|
326
|
-
context_window_artifacts: {
|
|
327
|
-
enabled: true,
|
|
328
|
-
min_file_lines: 100,
|
|
329
|
-
degradation_threshold: 0.4,
|
|
330
|
-
signals_required: 2,
|
|
331
|
-
},
|
|
332
|
-
},
|
|
333
|
-
output: {
|
|
334
|
-
report_path: 'rigour-report.json',
|
|
335
|
-
},
|
|
336
|
-
planned: [],
|
|
337
|
-
ignore: [],
|
|
338
|
-
};
|
package/src/types/fix-packet.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Fix Packet v2 Schema
|
|
5
|
-
* Designed for high-fidelity communication with AI agents during the refinement loop.
|
|
6
|
-
*/
|
|
7
|
-
export const FixPacketV2Schema = z.object({
|
|
8
|
-
version: z.literal(2),
|
|
9
|
-
goal: z.string().default('Achieve PASS state for all quality gates'),
|
|
10
|
-
violations: z.array(z.object({
|
|
11
|
-
id: z.string(),
|
|
12
|
-
gate: z.string(),
|
|
13
|
-
severity: z.enum(['low', 'medium', 'high', 'critical']).default('medium'),
|
|
14
|
-
category: z.string().optional(),
|
|
15
|
-
title: z.string(),
|
|
16
|
-
details: z.string(),
|
|
17
|
-
files: z.array(z.string()).optional(),
|
|
18
|
-
hint: z.string().optional(),
|
|
19
|
-
instructions: z.array(z.string()).optional(), // Step-by-step fix instructions
|
|
20
|
-
metrics: z.record(z.any()).optional(), // e.g., { complexity: 15, max: 10 }
|
|
21
|
-
})),
|
|
22
|
-
constraints: z.object({
|
|
23
|
-
protected_paths: z.array(z.string()).optional(),
|
|
24
|
-
do_not_touch: z.array(z.string()).optional(), // Alias for protected_paths
|
|
25
|
-
max_files_changed: z.number().optional(),
|
|
26
|
-
no_new_deps: z.boolean().optional().default(true),
|
|
27
|
-
allowed_dependencies: z.array(z.string()).optional(),
|
|
28
|
-
paradigm: z.string().optional(), // 'oop', 'functional'
|
|
29
|
-
}).optional().default({}),
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
export type FixPacketV2 = z.infer<typeof FixPacketV2Schema>;
|
package/src/types/index.ts
DELETED
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
export const GatesSchema = z.object({
|
|
4
|
-
max_file_lines: z.number().optional().default(500),
|
|
5
|
-
forbid_todos: z.boolean().optional().default(true),
|
|
6
|
-
forbid_fixme: z.boolean().optional().default(true),
|
|
7
|
-
forbid_paths: z.array(z.string()).optional().default([]),
|
|
8
|
-
required_files: z.array(z.string()).optional().default([
|
|
9
|
-
'docs/SPEC.md',
|
|
10
|
-
'docs/ARCH.md',
|
|
11
|
-
'docs/DECISIONS.md',
|
|
12
|
-
'docs/TASKS.md',
|
|
13
|
-
]),
|
|
14
|
-
ast: z.object({
|
|
15
|
-
complexity: z.number().optional().default(10),
|
|
16
|
-
max_methods: z.number().optional().default(10),
|
|
17
|
-
max_params: z.number().optional().default(5),
|
|
18
|
-
max_nesting: z.number().optional().default(4),
|
|
19
|
-
max_inheritance_depth: z.number().optional().default(3),
|
|
20
|
-
max_class_dependencies: z.number().optional().default(5),
|
|
21
|
-
max_function_lines: z.number().optional().default(50),
|
|
22
|
-
}).optional().default({}),
|
|
23
|
-
staleness: z.object({
|
|
24
|
-
enabled: z.boolean().optional().default(false),
|
|
25
|
-
// Rule-based staleness detection (toggle individual rules)
|
|
26
|
-
rules: z.record(z.boolean()).optional().default({
|
|
27
|
-
'no-var': true, // var → const/let (ES6+)
|
|
28
|
-
'no-commonjs': false, // require() → import
|
|
29
|
-
'no-arguments': false, // arguments → rest params
|
|
30
|
-
'prefer-arrow': false, // function → arrow function
|
|
31
|
-
'prefer-template': false, // 'a' + b → `a${b}`
|
|
32
|
-
'prefer-spread': false, // apply() → spread
|
|
33
|
-
'prefer-rest': false, // arguments → ...args
|
|
34
|
-
'prefer-const': false, // let (unchanged) → const
|
|
35
|
-
}),
|
|
36
|
-
}).optional().default({}),
|
|
37
|
-
dependencies: z.object({
|
|
38
|
-
forbid: z.array(z.string()).optional().default([]),
|
|
39
|
-
trusted_registry: z.string().optional(),
|
|
40
|
-
}).optional().default({}),
|
|
41
|
-
architecture: z.object({
|
|
42
|
-
boundaries: z.array(z.object({
|
|
43
|
-
from: z.string(),
|
|
44
|
-
to: z.string(),
|
|
45
|
-
mode: z.enum(['allow', 'deny']).default('deny'),
|
|
46
|
-
})).optional().default([]),
|
|
47
|
-
}).optional().default({}),
|
|
48
|
-
safety: z.object({
|
|
49
|
-
max_files_changed_per_cycle: z.number().optional().default(10),
|
|
50
|
-
protected_paths: z.array(z.string()).optional().default(['.github/**', 'docs/**', 'rigour.yml']),
|
|
51
|
-
}).optional().default({}),
|
|
52
|
-
context: z.object({
|
|
53
|
-
enabled: z.boolean().optional().default(true),
|
|
54
|
-
sensitivity: z.number().min(0).max(1).optional().default(0.8), // 0.8 correlation threshold
|
|
55
|
-
mining_depth: z.number().optional().default(100), // Number of files to sample
|
|
56
|
-
ignored_patterns: z.array(z.string()).optional().default([]),
|
|
57
|
-
// v2.14+ Extended Context for frontier models
|
|
58
|
-
cross_file_patterns: z.boolean().optional().default(true),
|
|
59
|
-
naming_consistency: z.boolean().optional().default(true),
|
|
60
|
-
import_relationships: z.boolean().optional().default(true),
|
|
61
|
-
max_cross_file_depth: z.number().optional().default(50),
|
|
62
|
-
}).optional().default({}),
|
|
63
|
-
environment: z.object({
|
|
64
|
-
enabled: z.boolean().optional().default(true),
|
|
65
|
-
enforce_contracts: z.boolean().optional().default(true), // Auto-discovery of versions from truth sources
|
|
66
|
-
tools: z.record(z.string()).optional().default({}), // Explicit overrides
|
|
67
|
-
required_env: z.array(z.string()).optional().default([]),
|
|
68
|
-
}).optional().default({}),
|
|
69
|
-
retry_loop_breaker: z.object({
|
|
70
|
-
enabled: z.boolean().optional().default(true),
|
|
71
|
-
max_retries: z.number().optional().default(3), // Fail after 3 consecutive failures in same category
|
|
72
|
-
auto_classify: z.boolean().optional().default(true), // Auto-detect failure category from error message
|
|
73
|
-
doc_sources: z.record(z.string()).optional().default({}), // Custom doc URLs per category
|
|
74
|
-
}).optional().default({}),
|
|
75
|
-
agent_team: z.object({
|
|
76
|
-
enabled: z.boolean().optional().default(false),
|
|
77
|
-
max_concurrent_agents: z.number().optional().default(3),
|
|
78
|
-
cross_agent_pattern_check: z.boolean().optional().default(true),
|
|
79
|
-
handoff_verification: z.boolean().optional().default(true),
|
|
80
|
-
task_ownership: z.enum(['strict', 'collaborative']).optional().default('strict'),
|
|
81
|
-
}).optional().default({}),
|
|
82
|
-
checkpoint: z.object({
|
|
83
|
-
enabled: z.boolean().optional().default(false),
|
|
84
|
-
interval_minutes: z.number().optional().default(15),
|
|
85
|
-
quality_threshold: z.number().optional().default(80),
|
|
86
|
-
drift_detection: z.boolean().optional().default(true),
|
|
87
|
-
auto_save_on_failure: z.boolean().optional().default(true),
|
|
88
|
-
}).optional().default({}),
|
|
89
|
-
security: z.object({
|
|
90
|
-
enabled: z.boolean().optional().default(true),
|
|
91
|
-
sql_injection: z.boolean().optional().default(true),
|
|
92
|
-
xss: z.boolean().optional().default(true),
|
|
93
|
-
path_traversal: z.boolean().optional().default(true),
|
|
94
|
-
hardcoded_secrets: z.boolean().optional().default(true),
|
|
95
|
-
insecure_randomness: z.boolean().optional().default(true),
|
|
96
|
-
command_injection: z.boolean().optional().default(true),
|
|
97
|
-
block_on_severity: z.enum(['critical', 'high', 'medium', 'low']).optional().default('high'),
|
|
98
|
-
}).optional().default({}),
|
|
99
|
-
adaptive: z.object({
|
|
100
|
-
enabled: z.boolean().optional().default(false),
|
|
101
|
-
base_coverage_threshold: z.number().optional().default(80),
|
|
102
|
-
base_quality_threshold: z.number().optional().default(80),
|
|
103
|
-
auto_detect_tier: z.boolean().optional().default(true),
|
|
104
|
-
forced_tier: z.enum(['hobby', 'startup', 'enterprise']).optional(),
|
|
105
|
-
}).optional().default({}),
|
|
106
|
-
// v2.16+ AI-Native Drift Detection Gates
|
|
107
|
-
duplication_drift: z.object({
|
|
108
|
-
enabled: z.boolean().optional().default(true),
|
|
109
|
-
similarity_threshold: z.number().min(0).max(1).optional().default(0.8),
|
|
110
|
-
min_body_lines: z.number().optional().default(5),
|
|
111
|
-
}).optional().default({}),
|
|
112
|
-
hallucinated_imports: z.object({
|
|
113
|
-
enabled: z.boolean().optional().default(true),
|
|
114
|
-
check_relative: z.boolean().optional().default(true),
|
|
115
|
-
check_packages: z.boolean().optional().default(true),
|
|
116
|
-
ignore_patterns: z.array(z.string()).optional().default([
|
|
117
|
-
'\\.css$', '\\.scss$', '\\.less$', '\\.svg$', '\\.png$', '\\.jpg$',
|
|
118
|
-
'\\.json$', '\\.wasm$', '\\.graphql$', '\\.gql$',
|
|
119
|
-
]),
|
|
120
|
-
}).optional().default({}),
|
|
121
|
-
inconsistent_error_handling: z.object({
|
|
122
|
-
enabled: z.boolean().optional().default(true),
|
|
123
|
-
max_strategies_per_type: z.number().optional().default(2),
|
|
124
|
-
min_occurrences: z.number().optional().default(3),
|
|
125
|
-
ignore_empty_catches: z.boolean().optional().default(false),
|
|
126
|
-
}).optional().default({}),
|
|
127
|
-
context_window_artifacts: z.object({
|
|
128
|
-
enabled: z.boolean().optional().default(true),
|
|
129
|
-
min_file_lines: z.number().optional().default(100),
|
|
130
|
-
degradation_threshold: z.number().min(0).max(1).optional().default(0.4),
|
|
131
|
-
signals_required: z.number().optional().default(2),
|
|
132
|
-
}).optional().default({}),
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
export const CommandsSchema = z.object({
|
|
136
|
-
format: z.string().optional(),
|
|
137
|
-
lint: z.string().optional(),
|
|
138
|
-
typecheck: z.string().optional(),
|
|
139
|
-
test: z.string().optional(),
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
export const ConfigSchema = z.object({
|
|
143
|
-
version: z.number().default(1),
|
|
144
|
-
preset: z.string().optional(),
|
|
145
|
-
paradigm: z.string().optional(),
|
|
146
|
-
commands: CommandsSchema.optional().default({}),
|
|
147
|
-
gates: GatesSchema.optional().default({}),
|
|
148
|
-
output: z.object({
|
|
149
|
-
report_path: z.string().default('rigour-report.json'),
|
|
150
|
-
}).optional().default({}),
|
|
151
|
-
planned: z.array(z.string()).optional().default([]),
|
|
152
|
-
ignore: z.array(z.string()).optional().default([]),
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
export type Gates = z.infer<typeof GatesSchema>;
|
|
156
|
-
export type Commands = z.infer<typeof CommandsSchema>;
|
|
157
|
-
export type Config = z.infer<typeof ConfigSchema>;
|
|
158
|
-
|
|
159
|
-
export type RawGates = z.input<typeof GatesSchema>;
|
|
160
|
-
export type RawCommands = z.input<typeof CommandsSchema>;
|
|
161
|
-
export type RawConfig = z.input<typeof ConfigSchema>;
|
|
162
|
-
|
|
163
|
-
export const StatusSchema = z.enum(['PASS', 'FAIL', 'SKIP', 'ERROR']);
|
|
164
|
-
export type Status = z.infer<typeof StatusSchema>;
|
|
165
|
-
|
|
166
|
-
export const SeveritySchema = z.enum(['critical', 'high', 'medium', 'low', 'info']);
|
|
167
|
-
export type Severity = z.infer<typeof SeveritySchema>;
|
|
168
|
-
|
|
169
|
-
/** Severity weights for score calculation */
|
|
170
|
-
export const SEVERITY_WEIGHTS: Record<Severity, number> = {
|
|
171
|
-
critical: 20,
|
|
172
|
-
high: 10,
|
|
173
|
-
medium: 5,
|
|
174
|
-
low: 2,
|
|
175
|
-
info: 0,
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
export const FailureSchema = z.object({
|
|
179
|
-
id: z.string(),
|
|
180
|
-
title: z.string(),
|
|
181
|
-
details: z.string(),
|
|
182
|
-
severity: SeveritySchema.optional(),
|
|
183
|
-
files: z.array(z.string()).optional(),
|
|
184
|
-
line: z.number().optional(),
|
|
185
|
-
endLine: z.number().optional(),
|
|
186
|
-
hint: z.string().optional(),
|
|
187
|
-
});
|
|
188
|
-
export type Failure = z.infer<typeof FailureSchema>;
|
|
189
|
-
|
|
190
|
-
export const ReportSchema = z.object({
|
|
191
|
-
status: StatusSchema,
|
|
192
|
-
summary: z.record(StatusSchema),
|
|
193
|
-
failures: z.array(FailureSchema),
|
|
194
|
-
stats: z.object({
|
|
195
|
-
duration_ms: z.number(),
|
|
196
|
-
score: z.number().optional(),
|
|
197
|
-
severity_breakdown: z.record(z.number()).optional(),
|
|
198
|
-
}),
|
|
199
|
-
});
|
|
200
|
-
export type Report = z.infer<typeof ReportSchema>;
|
package/src/utils/logger.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
|
|
3
|
-
export enum LogLevel {
|
|
4
|
-
DEBUG = 0,
|
|
5
|
-
INFO = 1,
|
|
6
|
-
WARN = 2,
|
|
7
|
-
ERROR = 3,
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export class Logger {
|
|
11
|
-
private static level: LogLevel = LogLevel.INFO;
|
|
12
|
-
|
|
13
|
-
static setLevel(level: LogLevel) {
|
|
14
|
-
this.level = level;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
static info(message: string) {
|
|
18
|
-
if (this.level <= LogLevel.INFO) {
|
|
19
|
-
console.error(chalk.blue('info: ') + message);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
static warn(message: string) {
|
|
24
|
-
if (this.level <= LogLevel.WARN) {
|
|
25
|
-
console.error(chalk.yellow('warn: ') + message);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
static error(message: string, error?: any) {
|
|
30
|
-
if (this.level <= LogLevel.ERROR) {
|
|
31
|
-
console.error(chalk.red('error: ') + message);
|
|
32
|
-
if (error) {
|
|
33
|
-
console.error(error);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
static debug(message: string) {
|
|
39
|
-
if (this.level <= LogLevel.DEBUG) {
|
|
40
|
-
console.error(chalk.dim('debug: ') + message);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import { FileScanner } from './scanner.js';
|
|
3
|
-
import { globby } from 'globby';
|
|
4
|
-
|
|
5
|
-
vi.mock('globby', () => ({
|
|
6
|
-
globby: vi.fn(),
|
|
7
|
-
}));
|
|
8
|
-
|
|
9
|
-
describe('FileScanner', () => {
|
|
10
|
-
it('should merge default ignores with user ignores', async () => {
|
|
11
|
-
const options = {
|
|
12
|
-
cwd: '/test',
|
|
13
|
-
ignore: ['custom-ignore']
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
await FileScanner.findFiles(options);
|
|
17
|
-
|
|
18
|
-
const call = vi.mocked(globby).mock.calls[0];
|
|
19
|
-
const ignore = (call[1] as any).ignore;
|
|
20
|
-
|
|
21
|
-
expect(ignore).toContain('**/node_modules/**');
|
|
22
|
-
expect(ignore).toContain('custom-ignore');
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('should normalize paths to forward slashes', async () => {
|
|
26
|
-
const options = {
|
|
27
|
-
cwd: 'C:\\test\\path',
|
|
28
|
-
patterns: ['**\\*.ts']
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
await FileScanner.findFiles(options);
|
|
32
|
-
|
|
33
|
-
const call = vi.mocked(globby).mock.calls[1];
|
|
34
|
-
expect(call[0][0]).toBe('**/*.ts');
|
|
35
|
-
expect(call[1]?.cwd).toBe('C:/test/path');
|
|
36
|
-
});
|
|
37
|
-
});
|
package/src/utils/scanner.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { globby } from 'globby';
|
|
2
|
-
import fs from 'fs-extra';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
|
|
5
|
-
export interface ScannerOptions {
|
|
6
|
-
cwd: string;
|
|
7
|
-
patterns?: string[];
|
|
8
|
-
ignore?: string[];
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export class FileScanner {
|
|
12
|
-
private static DEFAULT_PATTERNS = ['**/*.{ts,js,py,css,html,md}'];
|
|
13
|
-
private static DEFAULT_IGNORE = [
|
|
14
|
-
'**/node_modules/**',
|
|
15
|
-
'**/dist/**',
|
|
16
|
-
'**/package-lock.json',
|
|
17
|
-
'**/pnpm-lock.yaml',
|
|
18
|
-
'**/.git/**',
|
|
19
|
-
'rigour-report.json'
|
|
20
|
-
];
|
|
21
|
-
|
|
22
|
-
static async findFiles(options: ScannerOptions): Promise<string[]> {
|
|
23
|
-
const patterns = (options.patterns || this.DEFAULT_PATTERNS).map(p => p.replace(/\\/g, '/'));
|
|
24
|
-
const userIgnore = options.ignore || [];
|
|
25
|
-
const ignore = [...new Set([...this.DEFAULT_IGNORE, ...userIgnore])].map(p => p.replace(/\\/g, '/'));
|
|
26
|
-
const normalizedCwd = options.cwd.replace(/\\/g, '/');
|
|
27
|
-
|
|
28
|
-
return globby(patterns, {
|
|
29
|
-
cwd: normalizedCwd,
|
|
30
|
-
ignore: ignore,
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
static async readFiles(cwd: string, files: string[]): Promise<Map<string, string>> {
|
|
35
|
-
const contents = new Map<string, string>();
|
|
36
|
-
for (const file of files) {
|
|
37
|
-
const normalizedFile = file.replace(/\//g, path.sep);
|
|
38
|
-
const filePath = path.isAbsolute(normalizedFile) ? normalizedFile : path.join(cwd, normalizedFile);
|
|
39
|
-
contents.set(file, await fs.readFile(filePath, 'utf-8'));
|
|
40
|
-
}
|
|
41
|
-
return contents;
|
|
42
|
-
}
|
|
43
|
-
}
|