@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.
Files changed (103) hide show
  1. package/README.md +58 -0
  2. package/dist/context.test.js +2 -3
  3. package/dist/environment.test.js +2 -1
  4. package/dist/gates/agent-team.d.ts +2 -1
  5. package/dist/gates/agent-team.js +1 -0
  6. package/dist/gates/base.d.ts +3 -1
  7. package/dist/gates/base.js +3 -0
  8. package/dist/gates/checkpoint.d.ts +2 -1
  9. package/dist/gates/checkpoint.js +3 -2
  10. package/dist/gates/context-window-artifacts.d.ts +2 -1
  11. package/dist/gates/context-window-artifacts.js +6 -3
  12. package/dist/gates/context.d.ts +2 -1
  13. package/dist/gates/context.js +1 -0
  14. package/dist/gates/coverage.js +3 -1
  15. package/dist/gates/dependency.js +5 -5
  16. package/dist/gates/duplication-drift.d.ts +2 -1
  17. package/dist/gates/duplication-drift.js +4 -1
  18. package/dist/gates/environment.js +4 -4
  19. package/dist/gates/hallucinated-imports.d.ts +21 -2
  20. package/dist/gates/hallucinated-imports.js +116 -2
  21. package/dist/gates/inconsistent-error-handling.d.ts +2 -1
  22. package/dist/gates/inconsistent-error-handling.js +21 -7
  23. package/dist/gates/promise-safety.d.ts +68 -0
  24. package/dist/gates/promise-safety.js +509 -0
  25. package/dist/gates/retry-loop-breaker.d.ts +2 -1
  26. package/dist/gates/retry-loop-breaker.js +2 -1
  27. package/dist/gates/runner.js +34 -1
  28. package/dist/gates/safety.d.ts +2 -1
  29. package/dist/gates/safety.js +2 -1
  30. package/dist/gates/security-patterns.d.ts +2 -1
  31. package/dist/gates/security-patterns.js +1 -0
  32. package/dist/gates/structure.js +1 -1
  33. package/dist/index.d.ts +1 -0
  34. package/dist/index.js +1 -0
  35. package/dist/services/fix-packet-service.d.ts +0 -1
  36. package/dist/services/fix-packet-service.js +9 -14
  37. package/dist/services/score-history.d.ts +54 -0
  38. package/dist/services/score-history.js +122 -0
  39. package/dist/templates/index.js +169 -0
  40. package/dist/types/fix-packet.d.ts +5 -5
  41. package/dist/types/fix-packet.js +1 -1
  42. package/dist/types/index.d.ts +153 -0
  43. package/dist/types/index.js +19 -0
  44. package/package.json +21 -1
  45. package/src/context.test.ts +0 -256
  46. package/src/discovery.test.ts +0 -88
  47. package/src/discovery.ts +0 -112
  48. package/src/environment.test.ts +0 -115
  49. package/src/gates/agent-team.test.ts +0 -134
  50. package/src/gates/agent-team.ts +0 -210
  51. package/src/gates/ast-handlers/base.ts +0 -13
  52. package/src/gates/ast-handlers/python.ts +0 -145
  53. package/src/gates/ast-handlers/python_parser.py +0 -181
  54. package/src/gates/ast-handlers/typescript.ts +0 -264
  55. package/src/gates/ast-handlers/universal.ts +0 -184
  56. package/src/gates/ast.ts +0 -54
  57. package/src/gates/base.ts +0 -28
  58. package/src/gates/checkpoint.test.ts +0 -135
  59. package/src/gates/checkpoint.ts +0 -311
  60. package/src/gates/content.ts +0 -51
  61. package/src/gates/context-window-artifacts.ts +0 -277
  62. package/src/gates/context.ts +0 -270
  63. package/src/gates/coverage.ts +0 -74
  64. package/src/gates/dependency.ts +0 -108
  65. package/src/gates/duplication-drift.ts +0 -231
  66. package/src/gates/environment.ts +0 -94
  67. package/src/gates/file.ts +0 -46
  68. package/src/gates/hallucinated-imports.ts +0 -361
  69. package/src/gates/inconsistent-error-handling.ts +0 -254
  70. package/src/gates/retry-loop-breaker.ts +0 -151
  71. package/src/gates/runner.ts +0 -188
  72. package/src/gates/safety.ts +0 -56
  73. package/src/gates/security-patterns.test.ts +0 -162
  74. package/src/gates/security-patterns.ts +0 -306
  75. package/src/gates/structure.ts +0 -36
  76. package/src/index.ts +0 -13
  77. package/src/pattern-index/embeddings.ts +0 -84
  78. package/src/pattern-index/index.ts +0 -59
  79. package/src/pattern-index/indexer.test.ts +0 -276
  80. package/src/pattern-index/indexer.ts +0 -1023
  81. package/src/pattern-index/matcher.test.ts +0 -293
  82. package/src/pattern-index/matcher.ts +0 -493
  83. package/src/pattern-index/overrides.ts +0 -235
  84. package/src/pattern-index/security.ts +0 -151
  85. package/src/pattern-index/staleness.test.ts +0 -313
  86. package/src/pattern-index/staleness.ts +0 -568
  87. package/src/pattern-index/types.ts +0 -339
  88. package/src/safety.test.ts +0 -53
  89. package/src/services/adaptive-thresholds.test.ts +0 -189
  90. package/src/services/adaptive-thresholds.ts +0 -275
  91. package/src/services/context-engine.ts +0 -104
  92. package/src/services/fix-packet-service.ts +0 -42
  93. package/src/services/state-service.ts +0 -138
  94. package/src/smoke.test.ts +0 -18
  95. package/src/templates/index.ts +0 -338
  96. package/src/types/fix-packet.ts +0 -32
  97. package/src/types/index.ts +0 -200
  98. package/src/utils/logger.ts +0 -43
  99. package/src/utils/scanner.test.ts +0 -37
  100. package/src/utils/scanner.ts +0 -43
  101. package/tsconfig.json +0 -10
  102. package/vitest.config.ts +0 -7
  103. package/vitest.setup.ts +0 -30
@@ -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
  }
@@ -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
  }
@@ -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
  }
@@ -148,6 +148,7 @@ export class SecurityPatternsGate extends Gate {
148
148
  block_on_severity: config.block_on_severity ?? 'high',
149
149
  };
150
150
  }
151
+ get provenance() { return 'security'; }
151
152
  async run(context) {
152
153
  if (!this.config.enabled) {
153
154
  return [];
@@ -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
@@ -7,3 +7,4 @@ 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
9
  export * from './utils/logger.js';
10
+ export * from './services/score-history.js';
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.
@@ -2,5 +2,4 @@ import { Report, Config } from '../types/index.js';
2
2
  import { FixPacketV2 } from '../types/fix-packet.js';
3
3
  export declare class FixPacketService {
4
4
  generate(report: Report, config: Config): FixPacketV2;
5
- private inferSeverity;
6
5
  }
@@ -1,17 +1,22 @@
1
1
  import { FixPacketV2Schema } from '../types/fix-packet.js';
2
2
  export class FixPacketService {
3
3
  generate(report, config) {
4
- const violations = report.failures.map(f => ({
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: this.inferSeverity(f),
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] : [], // Use hint as first instruction
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
+ }
@@ -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;
@@ -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(),