@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/dist/gates/runner.js
CHANGED
|
@@ -17,6 +17,7 @@ import { DuplicationDriftGate } from './duplication-drift.js';
|
|
|
17
17
|
import { HallucinatedImportsGate } from './hallucinated-imports.js';
|
|
18
18
|
import { InconsistentErrorHandlingGate } from './inconsistent-error-handling.js';
|
|
19
19
|
import { ContextWindowArtifactsGate } from './context-window-artifacts.js';
|
|
20
|
+
import { PromiseSafetyGate } from './promise-safety.js';
|
|
20
21
|
import { execa } from 'execa';
|
|
21
22
|
import { Logger } from '../utils/logger.js';
|
|
22
23
|
export class GateRunner {
|
|
@@ -73,6 +74,10 @@ export class GateRunner {
|
|
|
73
74
|
if (this.config.gates.context_window_artifacts?.enabled !== false) {
|
|
74
75
|
this.gates.push(new ContextWindowArtifactsGate(this.config.gates.context_window_artifacts));
|
|
75
76
|
}
|
|
77
|
+
// v2.17+ Promise Safety Gate (async/promise AI failure modes)
|
|
78
|
+
if (this.config.gates.promise_safety?.enabled !== false) {
|
|
79
|
+
this.gates.push(new PromiseSafetyGate(this.config.gates.promise_safety));
|
|
80
|
+
}
|
|
76
81
|
// Environment Alignment Gate (Should be prioritized)
|
|
77
82
|
if (this.config.gates.environment?.enabled) {
|
|
78
83
|
this.gates.unshift(new EnvironmentGate(this.config.gates));
|
|
@@ -114,6 +119,8 @@ export class GateRunner {
|
|
|
114
119
|
id: gate.id,
|
|
115
120
|
title: `Gate Error: ${gate.title}`,
|
|
116
121
|
details: error.message,
|
|
122
|
+
severity: 'medium',
|
|
123
|
+
provenance: 'traditional',
|
|
117
124
|
hint: 'There was an internal error running this gate. Check the logs.',
|
|
118
125
|
});
|
|
119
126
|
}
|
|
@@ -137,6 +144,8 @@ export class GateRunner {
|
|
|
137
144
|
id: key,
|
|
138
145
|
title: `${key.toUpperCase()} Check Failed`,
|
|
139
146
|
details: error.stderr || error.stdout || error.message,
|
|
147
|
+
severity: 'medium',
|
|
148
|
+
provenance: 'traditional',
|
|
140
149
|
hint: `Fix the issues reported by \`${cmd}\`. Use rigorous standards (SOLID, DRY) in your resolution.`,
|
|
141
150
|
});
|
|
142
151
|
}
|
|
@@ -144,7 +153,6 @@ export class GateRunner {
|
|
|
144
153
|
}
|
|
145
154
|
const status = failures.length > 0 ? 'FAIL' : 'PASS';
|
|
146
155
|
// Severity-weighted scoring: each failure deducts based on its severity
|
|
147
|
-
// critical=20, high=10, medium=5, low=2, info=0
|
|
148
156
|
const severityBreakdown = {};
|
|
149
157
|
let totalDeduction = 0;
|
|
150
158
|
for (const f of failures) {
|
|
@@ -153,6 +161,23 @@ export class GateRunner {
|
|
|
153
161
|
totalDeduction += SEVERITY_WEIGHTS[sev] ?? 5;
|
|
154
162
|
}
|
|
155
163
|
const score = Math.max(0, 100 - totalDeduction);
|
|
164
|
+
// Two-score system: separate AI health from structural quality
|
|
165
|
+
let aiDeduction = 0;
|
|
166
|
+
let aiCount = 0;
|
|
167
|
+
let structuralDeduction = 0;
|
|
168
|
+
let structuralCount = 0;
|
|
169
|
+
for (const f of failures) {
|
|
170
|
+
const sev = (f.severity || 'medium');
|
|
171
|
+
const weight = SEVERITY_WEIGHTS[sev] ?? 5;
|
|
172
|
+
if (f.provenance === 'ai-drift') {
|
|
173
|
+
aiDeduction += weight;
|
|
174
|
+
aiCount++;
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
structuralDeduction += weight;
|
|
178
|
+
structuralCount++;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
156
181
|
return {
|
|
157
182
|
status,
|
|
158
183
|
summary,
|
|
@@ -160,7 +185,15 @@ export class GateRunner {
|
|
|
160
185
|
stats: {
|
|
161
186
|
duration_ms: Date.now() - start,
|
|
162
187
|
score,
|
|
188
|
+
ai_health_score: Math.max(0, 100 - aiDeduction),
|
|
189
|
+
structural_score: Math.max(0, 100 - structuralDeduction),
|
|
163
190
|
severity_breakdown: severityBreakdown,
|
|
191
|
+
provenance_breakdown: {
|
|
192
|
+
'ai-drift': aiCount,
|
|
193
|
+
traditional: structuralCount - failures.filter(f => f.provenance === 'security' || f.provenance === 'governance').length,
|
|
194
|
+
security: failures.filter(f => f.provenance === 'security').length,
|
|
195
|
+
governance: failures.filter(f => f.provenance === 'governance').length,
|
|
196
|
+
},
|
|
164
197
|
},
|
|
165
198
|
};
|
|
166
199
|
}
|
package/dist/gates/safety.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Gate, GateContext } from './base.js';
|
|
2
|
-
import { Failure, Gates } from '../types/index.js';
|
|
2
|
+
import { Failure, Gates, Provenance } from '../types/index.js';
|
|
3
3
|
export declare class FileGuardGate extends Gate {
|
|
4
4
|
private config;
|
|
5
5
|
constructor(config: Gates);
|
|
6
|
+
protected get provenance(): Provenance;
|
|
6
7
|
run(context: GateContext): Promise<Failure[]>;
|
|
7
8
|
private isProtected;
|
|
8
9
|
}
|
package/dist/gates/safety.js
CHANGED
|
@@ -6,6 +6,7 @@ export class FileGuardGate extends Gate {
|
|
|
6
6
|
super('file-guard', 'File Guard — Protected Paths');
|
|
7
7
|
this.config = config;
|
|
8
8
|
}
|
|
9
|
+
get provenance() { return 'governance'; }
|
|
9
10
|
async run(context) {
|
|
10
11
|
const failures = [];
|
|
11
12
|
const safety = this.config.safety || {};
|
|
@@ -27,7 +28,7 @@ export class FileGuardGate extends Gate {
|
|
|
27
28
|
for (const file of modifiedFiles) {
|
|
28
29
|
if (this.isProtected(file, protectedPaths)) {
|
|
29
30
|
const message = `Protected file '${file}' was modified.`;
|
|
30
|
-
failures.push(this.createFailure(message, [file], `Agents are forbidden from modifying files in ${protectedPaths.join(', ')}.`, message));
|
|
31
|
+
failures.push(this.createFailure(message, [file], `Agents are forbidden from modifying files in ${protectedPaths.join(', ')}.`, message, undefined, undefined, 'high'));
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* @since v2.14.0
|
|
16
16
|
*/
|
|
17
17
|
import { Gate, GateContext } from './base.js';
|
|
18
|
-
import { Failure } from '../types/index.js';
|
|
18
|
+
import { Failure, Provenance } from '../types/index.js';
|
|
19
19
|
export interface SecurityVulnerability {
|
|
20
20
|
type: string;
|
|
21
21
|
severity: 'critical' | 'high' | 'medium' | 'low';
|
|
@@ -39,6 +39,7 @@ export declare class SecurityPatternsGate extends Gate {
|
|
|
39
39
|
private config;
|
|
40
40
|
private severityOrder;
|
|
41
41
|
constructor(config?: SecurityPatternsConfig);
|
|
42
|
+
protected get provenance(): Provenance;
|
|
42
43
|
run(context: GateContext): Promise<Failure[]>;
|
|
43
44
|
private scanFileForVulnerabilities;
|
|
44
45
|
}
|
package/dist/gates/structure.js
CHANGED
|
@@ -17,7 +17,7 @@ export class StructureGate extends Gate {
|
|
|
17
17
|
}
|
|
18
18
|
if (missing.length > 0) {
|
|
19
19
|
return [
|
|
20
|
-
this.createFailure('The following required files are missing:', missing, 'Create these files to maintain project documentation and consistency.'),
|
|
20
|
+
this.createFailure('The following required files are missing:', missing, 'Create these files to maintain project documentation and consistency.', undefined, undefined, undefined, 'low'),
|
|
21
21
|
];
|
|
22
22
|
}
|
|
23
23
|
return [];
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ 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
9
|
export * from './utils/logger.js';
|
|
10
|
+
export * from './services/score-history.js';
|
|
10
11
|
// Pattern Index is intentionally NOT exported here to prevent
|
|
11
12
|
// native dependency issues (sharp/transformers) from leaking into
|
|
12
13
|
// non-AI parts of the system.
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import { FixPacketV2Schema } from '../types/fix-packet.js';
|
|
2
2
|
export class FixPacketService {
|
|
3
3
|
generate(report, config) {
|
|
4
|
-
|
|
4
|
+
// Sort violations: critical first, then high, medium, low, info
|
|
5
|
+
const severityOrder = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };
|
|
6
|
+
const violations = report.failures
|
|
7
|
+
.map(f => ({
|
|
5
8
|
id: f.id,
|
|
6
9
|
gate: f.id,
|
|
7
|
-
severity:
|
|
10
|
+
severity: (f.severity || 'medium'),
|
|
11
|
+
category: f.provenance,
|
|
8
12
|
title: f.title,
|
|
9
13
|
details: f.details,
|
|
10
14
|
files: f.files,
|
|
11
15
|
hint: f.hint,
|
|
12
|
-
instructions: f.hint ? [f.hint] : [],
|
|
16
|
+
instructions: f.hint ? [f.hint] : [],
|
|
13
17
|
metrics: f.metrics,
|
|
14
|
-
}))
|
|
18
|
+
}))
|
|
19
|
+
.sort((a, b) => (severityOrder[a.severity] ?? 2) - (severityOrder[b.severity] ?? 2));
|
|
15
20
|
const packet = {
|
|
16
21
|
version: 2,
|
|
17
22
|
goal: "Achieve PASS state by resolving all listed engineering violations.",
|
|
@@ -26,14 +31,4 @@ export class FixPacketService {
|
|
|
26
31
|
};
|
|
27
32
|
return FixPacketV2Schema.parse(packet);
|
|
28
33
|
}
|
|
29
|
-
inferSeverity(f) {
|
|
30
|
-
// High complexity or God objects are usually High severity
|
|
31
|
-
if (f.id === 'ast-analysis')
|
|
32
|
-
return 'high';
|
|
33
|
-
// Unit test or Lint failures are Medium
|
|
34
|
-
if (f.id === 'test' || f.id === 'lint')
|
|
35
|
-
return 'medium';
|
|
36
|
-
// Documentation or small file size issues are Low
|
|
37
|
-
return 'medium';
|
|
38
|
-
}
|
|
39
34
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Score History Service
|
|
3
|
+
*
|
|
4
|
+
* Append-only JSONL tracking of quality scores over time.
|
|
5
|
+
* Used for compliance dashboards, trend analysis, and audit reports.
|
|
6
|
+
*
|
|
7
|
+
* Uses JSONL (not JSON) to avoid read-modify-write race conditions
|
|
8
|
+
* when multiple agents run checks concurrently.
|
|
9
|
+
*
|
|
10
|
+
* @since v2.17.0
|
|
11
|
+
*/
|
|
12
|
+
export interface ScoreEntry {
|
|
13
|
+
timestamp: string;
|
|
14
|
+
status: 'PASS' | 'FAIL' | 'SKIP' | 'ERROR';
|
|
15
|
+
score: number;
|
|
16
|
+
ai_health_score?: number;
|
|
17
|
+
structural_score?: number;
|
|
18
|
+
failureCount: number;
|
|
19
|
+
severity_breakdown: Record<string, number>;
|
|
20
|
+
provenance_breakdown: Record<string, number>;
|
|
21
|
+
}
|
|
22
|
+
export interface ScoreTrend {
|
|
23
|
+
direction: 'improving' | 'stable' | 'degrading';
|
|
24
|
+
delta: number;
|
|
25
|
+
recentAvg: number;
|
|
26
|
+
previousAvg: number;
|
|
27
|
+
recentScores: number[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Record a score entry after a rigour check run.
|
|
31
|
+
* Appends a single JSONL line. Auto-trims to MAX_ENTRIES.
|
|
32
|
+
*/
|
|
33
|
+
export declare function recordScore(cwd: string, report: {
|
|
34
|
+
status: string;
|
|
35
|
+
stats: {
|
|
36
|
+
score?: number;
|
|
37
|
+
ai_health_score?: number;
|
|
38
|
+
structural_score?: number;
|
|
39
|
+
severity_breakdown?: Record<string, number>;
|
|
40
|
+
provenance_breakdown?: Record<string, number>;
|
|
41
|
+
};
|
|
42
|
+
failures: {
|
|
43
|
+
length: number;
|
|
44
|
+
} | any[];
|
|
45
|
+
}): void;
|
|
46
|
+
/**
|
|
47
|
+
* Read the last N score entries.
|
|
48
|
+
*/
|
|
49
|
+
export declare function getScoreHistory(cwd: string, limit?: number): ScoreEntry[];
|
|
50
|
+
/**
|
|
51
|
+
* Calculate score trend from history.
|
|
52
|
+
* Compares average of last 5 runs vs previous 5 runs.
|
|
53
|
+
*/
|
|
54
|
+
export declare function getScoreTrend(cwd: string): ScoreTrend | null;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Score History Service
|
|
3
|
+
*
|
|
4
|
+
* Append-only JSONL tracking of quality scores over time.
|
|
5
|
+
* Used for compliance dashboards, trend analysis, and audit reports.
|
|
6
|
+
*
|
|
7
|
+
* Uses JSONL (not JSON) to avoid read-modify-write race conditions
|
|
8
|
+
* when multiple agents run checks concurrently.
|
|
9
|
+
*
|
|
10
|
+
* @since v2.17.0
|
|
11
|
+
*/
|
|
12
|
+
import * as fs from 'fs';
|
|
13
|
+
import * as path from 'path';
|
|
14
|
+
const MAX_ENTRIES = 100;
|
|
15
|
+
const HISTORY_FILE = 'score-history.jsonl';
|
|
16
|
+
function getHistoryPath(cwd) {
|
|
17
|
+
return path.join(cwd, '.rigour', HISTORY_FILE);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Record a score entry after a rigour check run.
|
|
21
|
+
* Appends a single JSONL line. Auto-trims to MAX_ENTRIES.
|
|
22
|
+
*/
|
|
23
|
+
export function recordScore(cwd, report) {
|
|
24
|
+
try {
|
|
25
|
+
const rigourDir = path.join(cwd, '.rigour');
|
|
26
|
+
if (!fs.existsSync(rigourDir)) {
|
|
27
|
+
fs.mkdirSync(rigourDir, { recursive: true });
|
|
28
|
+
}
|
|
29
|
+
const entry = {
|
|
30
|
+
timestamp: new Date().toISOString(),
|
|
31
|
+
status: report.status,
|
|
32
|
+
score: report.stats.score ?? 100,
|
|
33
|
+
ai_health_score: report.stats.ai_health_score,
|
|
34
|
+
structural_score: report.stats.structural_score,
|
|
35
|
+
failureCount: Array.isArray(report.failures) ? report.failures.length : 0,
|
|
36
|
+
severity_breakdown: report.stats.severity_breakdown ?? {},
|
|
37
|
+
provenance_breakdown: report.stats.provenance_breakdown ?? {},
|
|
38
|
+
};
|
|
39
|
+
const historyPath = getHistoryPath(cwd);
|
|
40
|
+
fs.appendFileSync(historyPath, JSON.stringify(entry) + '\n');
|
|
41
|
+
// Auto-trim if over MAX_ENTRIES
|
|
42
|
+
trimHistory(historyPath);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// Silent fail — score tracking should never break the check command
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Read the last N score entries.
|
|
50
|
+
*/
|
|
51
|
+
export function getScoreHistory(cwd, limit = 20) {
|
|
52
|
+
try {
|
|
53
|
+
const historyPath = getHistoryPath(cwd);
|
|
54
|
+
if (!fs.existsSync(historyPath))
|
|
55
|
+
return [];
|
|
56
|
+
const lines = fs.readFileSync(historyPath, 'utf-8')
|
|
57
|
+
.trim()
|
|
58
|
+
.split('\n')
|
|
59
|
+
.filter(line => line.length > 0);
|
|
60
|
+
const entries = lines.map(line => JSON.parse(line));
|
|
61
|
+
return entries.slice(-limit);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Calculate score trend from history.
|
|
69
|
+
* Compares average of last 5 runs vs previous 5 runs.
|
|
70
|
+
*/
|
|
71
|
+
export function getScoreTrend(cwd) {
|
|
72
|
+
const history = getScoreHistory(cwd, 20);
|
|
73
|
+
if (history.length < 3)
|
|
74
|
+
return null;
|
|
75
|
+
const scores = history.map(e => e.score);
|
|
76
|
+
const recentScores = scores.slice(-5);
|
|
77
|
+
const previousScores = scores.slice(-10, -5);
|
|
78
|
+
const recentAvg = recentScores.reduce((a, b) => a + b, 0) / recentScores.length;
|
|
79
|
+
if (previousScores.length === 0) {
|
|
80
|
+
return {
|
|
81
|
+
direction: 'stable',
|
|
82
|
+
delta: 0,
|
|
83
|
+
recentAvg: Math.round(recentAvg),
|
|
84
|
+
previousAvg: Math.round(recentAvg),
|
|
85
|
+
recentScores,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const previousAvg = previousScores.reduce((a, b) => a + b, 0) / previousScores.length;
|
|
89
|
+
const delta = recentAvg - previousAvg;
|
|
90
|
+
let direction;
|
|
91
|
+
if (delta > 3)
|
|
92
|
+
direction = 'improving';
|
|
93
|
+
else if (delta < -3)
|
|
94
|
+
direction = 'degrading';
|
|
95
|
+
else
|
|
96
|
+
direction = 'stable';
|
|
97
|
+
return {
|
|
98
|
+
direction,
|
|
99
|
+
delta: Math.round(delta * 10) / 10,
|
|
100
|
+
recentAvg: Math.round(recentAvg),
|
|
101
|
+
previousAvg: Math.round(previousAvg),
|
|
102
|
+
recentScores,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Trim JSONL file to last MAX_ENTRIES lines.
|
|
107
|
+
*/
|
|
108
|
+
function trimHistory(historyPath) {
|
|
109
|
+
try {
|
|
110
|
+
const lines = fs.readFileSync(historyPath, 'utf-8')
|
|
111
|
+
.trim()
|
|
112
|
+
.split('\n')
|
|
113
|
+
.filter(line => line.length > 0);
|
|
114
|
+
if (lines.length > MAX_ENTRIES) {
|
|
115
|
+
const trimmed = lines.slice(-MAX_ENTRIES);
|
|
116
|
+
fs.writeFileSync(historyPath, trimmed.join('\n') + '\n');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// Silent fail
|
|
121
|
+
}
|
|
122
|
+
}
|
package/dist/templates/index.js
CHANGED
|
@@ -135,6 +135,167 @@ export const TEMPLATES = [
|
|
|
135
135
|
],
|
|
136
136
|
},
|
|
137
137
|
},
|
|
138
|
+
// --- Regulated Industry Presets ---
|
|
139
|
+
{
|
|
140
|
+
name: 'healthcare',
|
|
141
|
+
markers: [
|
|
142
|
+
'hl7', 'fhir', 'hipaa', 'medical', 'patient', 'health',
|
|
143
|
+
'ehr', 'phi', 'dicom', 'icd-10', 'snomed',
|
|
144
|
+
],
|
|
145
|
+
config: {
|
|
146
|
+
preset: 'healthcare',
|
|
147
|
+
ignore: [
|
|
148
|
+
'.git/**', 'node_modules/**', 'dist/**', 'build/**',
|
|
149
|
+
'venv/**', '.venv/**', '__pycache__/**',
|
|
150
|
+
],
|
|
151
|
+
gates: {
|
|
152
|
+
max_file_lines: 300,
|
|
153
|
+
required_files: ['docs/COMPLIANCE.md', 'docs/SPEC.md', 'docs/ARCH.md', 'README.md'],
|
|
154
|
+
security: {
|
|
155
|
+
enabled: true,
|
|
156
|
+
sql_injection: true,
|
|
157
|
+
xss: true,
|
|
158
|
+
path_traversal: true,
|
|
159
|
+
hardcoded_secrets: true,
|
|
160
|
+
insecure_randomness: true,
|
|
161
|
+
command_injection: true,
|
|
162
|
+
block_on_severity: 'critical',
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
name: 'fintech',
|
|
169
|
+
markers: [
|
|
170
|
+
'trading', 'payment', 'kyc', 'aml', 'pci', 'transaction',
|
|
171
|
+
'ledger', 'banking', 'stripe', 'plaid', 'sox',
|
|
172
|
+
],
|
|
173
|
+
config: {
|
|
174
|
+
preset: 'fintech',
|
|
175
|
+
ignore: [
|
|
176
|
+
'.git/**', 'node_modules/**', 'dist/**', 'build/**',
|
|
177
|
+
'venv/**', '.venv/**', '__pycache__/**', 'vendor/**',
|
|
178
|
+
],
|
|
179
|
+
gates: {
|
|
180
|
+
max_file_lines: 350,
|
|
181
|
+
required_files: ['docs/AUDIT_LOG.md', 'docs/SPEC.md', 'docs/ARCH.md', 'README.md'],
|
|
182
|
+
security: {
|
|
183
|
+
enabled: true,
|
|
184
|
+
sql_injection: true,
|
|
185
|
+
xss: true,
|
|
186
|
+
path_traversal: true,
|
|
187
|
+
hardcoded_secrets: true,
|
|
188
|
+
insecure_randomness: true,
|
|
189
|
+
command_injection: true,
|
|
190
|
+
block_on_severity: 'high',
|
|
191
|
+
},
|
|
192
|
+
agent_team: {
|
|
193
|
+
enabled: true,
|
|
194
|
+
max_concurrent_agents: 3,
|
|
195
|
+
cross_agent_pattern_check: true,
|
|
196
|
+
handoff_verification: true,
|
|
197
|
+
task_ownership: 'strict',
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: 'government',
|
|
204
|
+
markers: [
|
|
205
|
+
'fedramp', 'nist', 'cmmc', 'federal', 'govcloud',
|
|
206
|
+
'il4', 'il5', 'fisma', 'itar', 'cui',
|
|
207
|
+
],
|
|
208
|
+
config: {
|
|
209
|
+
preset: 'government',
|
|
210
|
+
ignore: [
|
|
211
|
+
'.git/**', 'node_modules/**', 'dist/**', 'build/**',
|
|
212
|
+
'venv/**', '.venv/**', '__pycache__/**', 'vendor/**',
|
|
213
|
+
],
|
|
214
|
+
gates: {
|
|
215
|
+
max_file_lines: 250,
|
|
216
|
+
required_files: ['docs/SECURITY.md', 'docs/SPEC.md', 'docs/ARCH.md', 'README.md'],
|
|
217
|
+
ast: {
|
|
218
|
+
complexity: 8,
|
|
219
|
+
max_methods: 10,
|
|
220
|
+
max_params: 4,
|
|
221
|
+
max_nesting: 3,
|
|
222
|
+
max_inheritance_depth: 3,
|
|
223
|
+
max_class_dependencies: 5,
|
|
224
|
+
max_function_lines: 40,
|
|
225
|
+
},
|
|
226
|
+
security: {
|
|
227
|
+
enabled: true,
|
|
228
|
+
sql_injection: true,
|
|
229
|
+
xss: true,
|
|
230
|
+
path_traversal: true,
|
|
231
|
+
hardcoded_secrets: true,
|
|
232
|
+
insecure_randomness: true,
|
|
233
|
+
command_injection: true,
|
|
234
|
+
block_on_severity: 'medium',
|
|
235
|
+
},
|
|
236
|
+
agent_team: {
|
|
237
|
+
enabled: true,
|
|
238
|
+
max_concurrent_agents: 3,
|
|
239
|
+
cross_agent_pattern_check: true,
|
|
240
|
+
handoff_verification: true,
|
|
241
|
+
task_ownership: 'strict',
|
|
242
|
+
},
|
|
243
|
+
checkpoint: {
|
|
244
|
+
enabled: true,
|
|
245
|
+
interval_minutes: 10,
|
|
246
|
+
quality_threshold: 85,
|
|
247
|
+
drift_detection: true,
|
|
248
|
+
auto_save_on_failure: true,
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
// DevSecOps / Security SRE preset
|
|
254
|
+
{
|
|
255
|
+
name: 'devsecops',
|
|
256
|
+
markers: [
|
|
257
|
+
'trivy', 'snyk', 'semgrep', 'sonarqube', 'owasp',
|
|
258
|
+
'sast', 'dast', 'pentest', 'vulnerability', 'cve',
|
|
259
|
+
'security-scan', 'falco', 'wazuh', 'ossec',
|
|
260
|
+
],
|
|
261
|
+
config: {
|
|
262
|
+
preset: 'devsecops',
|
|
263
|
+
ignore: [
|
|
264
|
+
'.git/**', 'node_modules/**', 'dist/**', 'build/**',
|
|
265
|
+
'venv/**', '.venv/**', '__pycache__/**', 'vendor/**',
|
|
266
|
+
],
|
|
267
|
+
gates: {
|
|
268
|
+
max_file_lines: 300,
|
|
269
|
+
required_files: ['docs/SECURITY.md', 'docs/RUNBOOK.md', 'README.md'],
|
|
270
|
+
ast: {
|
|
271
|
+
complexity: 10,
|
|
272
|
+
max_methods: 10,
|
|
273
|
+
max_params: 5,
|
|
274
|
+
max_nesting: 3,
|
|
275
|
+
max_inheritance_depth: 3,
|
|
276
|
+
max_class_dependencies: 5,
|
|
277
|
+
max_function_lines: 50,
|
|
278
|
+
},
|
|
279
|
+
security: {
|
|
280
|
+
enabled: true,
|
|
281
|
+
sql_injection: true,
|
|
282
|
+
xss: true,
|
|
283
|
+
path_traversal: true,
|
|
284
|
+
hardcoded_secrets: true,
|
|
285
|
+
insecure_randomness: true,
|
|
286
|
+
command_injection: true,
|
|
287
|
+
block_on_severity: 'high',
|
|
288
|
+
},
|
|
289
|
+
agent_team: {
|
|
290
|
+
enabled: true,
|
|
291
|
+
max_concurrent_agents: 3,
|
|
292
|
+
cross_agent_pattern_check: true,
|
|
293
|
+
handoff_verification: true,
|
|
294
|
+
task_ownership: 'strict',
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
},
|
|
138
299
|
];
|
|
139
300
|
export const PARADIGM_TEMPLATES = [
|
|
140
301
|
{
|
|
@@ -312,6 +473,14 @@ export const UNIVERSAL_CONFIG = {
|
|
|
312
473
|
degradation_threshold: 0.4,
|
|
313
474
|
signals_required: 2,
|
|
314
475
|
},
|
|
476
|
+
promise_safety: {
|
|
477
|
+
enabled: true,
|
|
478
|
+
check_unhandled_then: true,
|
|
479
|
+
check_unsafe_parse: true,
|
|
480
|
+
check_async_without_await: true,
|
|
481
|
+
check_unsafe_fetch: true,
|
|
482
|
+
ignore_patterns: [],
|
|
483
|
+
},
|
|
315
484
|
},
|
|
316
485
|
output: {
|
|
317
486
|
report_path: 'rigour-report.json',
|
|
@@ -9,7 +9,7 @@ export declare const FixPacketV2Schema: z.ZodObject<{
|
|
|
9
9
|
violations: z.ZodArray<z.ZodObject<{
|
|
10
10
|
id: z.ZodString;
|
|
11
11
|
gate: z.ZodString;
|
|
12
|
-
severity: z.ZodDefault<z.ZodEnum<["low", "medium", "high", "critical"]>>;
|
|
12
|
+
severity: z.ZodDefault<z.ZodEnum<["info", "low", "medium", "high", "critical"]>>;
|
|
13
13
|
category: z.ZodOptional<z.ZodString>;
|
|
14
14
|
title: z.ZodString;
|
|
15
15
|
details: z.ZodString;
|
|
@@ -21,7 +21,7 @@ export declare const FixPacketV2Schema: z.ZodObject<{
|
|
|
21
21
|
id: string;
|
|
22
22
|
title: string;
|
|
23
23
|
details: string;
|
|
24
|
-
severity: "critical" | "high" | "medium" | "low";
|
|
24
|
+
severity: "critical" | "high" | "medium" | "low" | "info";
|
|
25
25
|
gate: string;
|
|
26
26
|
files?: string[] | undefined;
|
|
27
27
|
hint?: string | undefined;
|
|
@@ -33,7 +33,7 @@ export declare const FixPacketV2Schema: z.ZodObject<{
|
|
|
33
33
|
title: string;
|
|
34
34
|
details: string;
|
|
35
35
|
gate: string;
|
|
36
|
-
severity?: "critical" | "high" | "medium" | "low" | undefined;
|
|
36
|
+
severity?: "critical" | "high" | "medium" | "low" | "info" | undefined;
|
|
37
37
|
files?: string[] | undefined;
|
|
38
38
|
hint?: string | undefined;
|
|
39
39
|
category?: string | undefined;
|
|
@@ -69,7 +69,7 @@ export declare const FixPacketV2Schema: z.ZodObject<{
|
|
|
69
69
|
id: string;
|
|
70
70
|
title: string;
|
|
71
71
|
details: string;
|
|
72
|
-
severity: "critical" | "high" | "medium" | "low";
|
|
72
|
+
severity: "critical" | "high" | "medium" | "low" | "info";
|
|
73
73
|
gate: string;
|
|
74
74
|
files?: string[] | undefined;
|
|
75
75
|
hint?: string | undefined;
|
|
@@ -92,7 +92,7 @@ export declare const FixPacketV2Schema: z.ZodObject<{
|
|
|
92
92
|
title: string;
|
|
93
93
|
details: string;
|
|
94
94
|
gate: string;
|
|
95
|
-
severity?: "critical" | "high" | "medium" | "low" | undefined;
|
|
95
|
+
severity?: "critical" | "high" | "medium" | "low" | "info" | undefined;
|
|
96
96
|
files?: string[] | undefined;
|
|
97
97
|
hint?: string | undefined;
|
|
98
98
|
category?: string | undefined;
|
package/dist/types/fix-packet.js
CHANGED
|
@@ -9,7 +9,7 @@ export const FixPacketV2Schema = z.object({
|
|
|
9
9
|
violations: z.array(z.object({
|
|
10
10
|
id: z.string(),
|
|
11
11
|
gate: z.string(),
|
|
12
|
-
severity: z.enum(['low', 'medium', 'high', 'critical']).default('medium'),
|
|
12
|
+
severity: z.enum(['info', 'low', 'medium', 'high', 'critical']).default('medium'),
|
|
13
13
|
category: z.string().optional(),
|
|
14
14
|
title: z.string(),
|
|
15
15
|
details: z.string(),
|