@rigour-labs/core 4.3.4 → 4.3.5

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.
@@ -1,8 +1,9 @@
1
1
  import { FixPacketV2Schema } from '../types/fix-packet.js';
2
2
  export class FixPacketService {
3
3
  generate(report, config) {
4
- // Sort violations: critical first, then high, medium, low, info
5
4
  const severityOrder = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };
5
+ // Deduplicate failed gate IDs
6
+ const failedGates = [...new Set(report.failures.map(f => f.id))];
6
7
  const violations = report.failures
7
8
  .map(f => ({
8
9
  id: f.id,
@@ -12,19 +13,32 @@ export class FixPacketService {
12
13
  title: f.title,
13
14
  details: f.details,
14
15
  files: f.files,
16
+ locations: buildLocations(f),
15
17
  hint: f.hint,
16
- instructions: f.hint ? [f.hint] : [],
18
+ instructions: buildInstructions(f),
17
19
  metrics: f.metrics,
18
20
  }))
19
21
  .sort((a, b) => (severityOrder[a.severity] ?? 2) - (severityOrder[b.severity] ?? 2));
22
+ // Build verification commands from config.commands
23
+ const verification = buildVerification(config);
24
+ // Build allowed scope from violation files (what the agent should touch)
25
+ const violationFiles = violations.flatMap(v => v.files || []);
26
+ const uniqueFiles = [...new Set(violationFiles.map(f => {
27
+ // Strip metadata like "(600 lines)" from file paths
28
+ const clean = f.replace(/\s*\(.*?\)\s*$/, '').trim();
29
+ return clean;
30
+ }))];
20
31
  const packet = {
21
- version: 2,
32
+ version: 3,
22
33
  goal: "Achieve PASS state by resolving all listed engineering violations.",
34
+ failed_gates: failedGates,
23
35
  violations,
36
+ verification,
24
37
  constraints: {
25
38
  paradigm: config.paradigm,
26
39
  protected_paths: config.gates.safety?.protected_paths,
27
40
  do_not_touch: config.gates.safety?.protected_paths,
41
+ allowed_scope: uniqueFiles.length > 0 ? uniqueFiles : undefined,
28
42
  max_files_changed: config.gates.safety?.max_files_changed_per_cycle,
29
43
  no_new_deps: true,
30
44
  },
@@ -32,3 +46,86 @@ export class FixPacketService {
32
46
  return FixPacketV2Schema.parse(packet);
33
47
  }
34
48
  }
49
+ /**
50
+ * Build precise locations from failure's files + line numbers.
51
+ * If failure has both files[] and line/endLine, create a location per file.
52
+ * If only files[], locations are file-level (no line numbers).
53
+ */
54
+ function buildLocations(f) {
55
+ if (!f.files || f.files.length === 0)
56
+ return undefined;
57
+ return f.files.map(file => {
58
+ const loc = {
59
+ file: file.replace(/\s*\(.*?\)\s*$/, '').trim(),
60
+ };
61
+ // If the failure has line numbers and there's only one file, attach them
62
+ if (f.files.length === 1) {
63
+ if (f.line)
64
+ loc.line = f.line;
65
+ if (f.endLine)
66
+ loc.endLine = f.endLine;
67
+ }
68
+ return loc;
69
+ });
70
+ }
71
+ /**
72
+ * Build step-by-step instructions from the hint and failure context.
73
+ */
74
+ function buildInstructions(f) {
75
+ const steps = [];
76
+ if (f.hint)
77
+ steps.push(f.hint);
78
+ // Add gate-specific guidance
79
+ switch (f.id) {
80
+ case 'file-size':
81
+ steps.push('Break the file into smaller modules following Single Responsibility Principle');
82
+ break;
83
+ case 'hallucinated-imports':
84
+ steps.push('Remove or replace the non-existent import with a real package');
85
+ break;
86
+ case 'phantom-apis':
87
+ steps.push('Check the actual API surface of the module and use a real method');
88
+ break;
89
+ case 'forbid-todos':
90
+ steps.push('Resolve the TODO/FIXME comment or remove it if no longer relevant');
91
+ break;
92
+ case 'security-patterns':
93
+ steps.push('Apply the security fix described above. Do NOT suppress the warning.');
94
+ break;
95
+ case 'promise-safety':
96
+ steps.push('Add proper error handling (try/catch or .catch()) to async operations');
97
+ break;
98
+ case 'deprecated-apis':
99
+ steps.push('Replace deprecated API usage with the recommended modern alternative');
100
+ break;
101
+ case 'duplication-drift':
102
+ steps.push('Extract the duplicated logic into a shared utility or module');
103
+ break;
104
+ case 'inconsistent-error-handling':
105
+ steps.push('Align error handling strategy across the module');
106
+ break;
107
+ }
108
+ return steps.length > 0 ? steps : [];
109
+ }
110
+ /**
111
+ * Build verification block from config.commands.
112
+ * These are the commands the agent MUST run after fixing to prove the fix works.
113
+ */
114
+ function buildVerification(config) {
115
+ const commands = [];
116
+ if (config.commands?.typecheck) {
117
+ commands.push({ cmd: config.commands.typecheck, purpose: 'Ensure no type errors after changes' });
118
+ }
119
+ if (config.commands?.lint) {
120
+ commands.push({ cmd: config.commands.lint, purpose: 'Ensure no lint violations' });
121
+ }
122
+ if (config.commands?.test) {
123
+ commands.push({ cmd: config.commands.test, purpose: 'Ensure all tests pass' });
124
+ }
125
+ if (config.commands?.format) {
126
+ commands.push({ cmd: config.commands.format, purpose: 'Ensure code formatting is correct' });
127
+ }
128
+ // Always end with rigour check
129
+ commands.push({ cmd: 'rigour_check', purpose: 'Re-run all quality gates to confirm PASS' });
130
+ return { commands, gate_command: 'rigour_check' };
131
+ }
@@ -1,11 +1,91 @@
1
1
  import { z } from 'zod';
2
2
  /**
3
- * Fix Packet v2 Schema
4
- * Designed for high-fidelity communication with AI agents during the refinement loop.
3
+ * Fix Packet v3 Schema
4
+ *
5
+ * Designed for high-fidelity, machine-readable communication with AI agents.
6
+ * Every violation tells the agent exactly: who failed, which files, what rule,
7
+ * where in the file, and what must pass to verify the fix.
8
+ *
9
+ * v3 changes from v2:
10
+ * - Violations now include `location` (file + line range) for precise targeting
11
+ * - Top-level `verification` block: commands the agent MUST run after fixing
12
+ * - `allowed_scope`: explicit list of file globs the agent IS allowed to edit
13
+ * - `failed_gates`: summary list of gate IDs that failed (quick machine check)
5
14
  */
15
+ declare const ViolationLocationSchema: z.ZodObject<{
16
+ file: z.ZodString;
17
+ line: z.ZodOptional<z.ZodNumber>;
18
+ endLine: z.ZodOptional<z.ZodNumber>;
19
+ }, "strip", z.ZodTypeAny, {
20
+ file: string;
21
+ line?: number | undefined;
22
+ endLine?: number | undefined;
23
+ }, {
24
+ file: string;
25
+ line?: number | undefined;
26
+ endLine?: number | undefined;
27
+ }>;
28
+ declare const ViolationSchema: z.ZodObject<{
29
+ id: z.ZodString;
30
+ gate: z.ZodString;
31
+ severity: z.ZodDefault<z.ZodEnum<["info", "low", "medium", "high", "critical"]>>;
32
+ category: z.ZodOptional<z.ZodString>;
33
+ title: z.ZodString;
34
+ details: z.ZodString;
35
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
36
+ locations: z.ZodOptional<z.ZodArray<z.ZodObject<{
37
+ file: z.ZodString;
38
+ line: z.ZodOptional<z.ZodNumber>;
39
+ endLine: z.ZodOptional<z.ZodNumber>;
40
+ }, "strip", z.ZodTypeAny, {
41
+ file: string;
42
+ line?: number | undefined;
43
+ endLine?: number | undefined;
44
+ }, {
45
+ file: string;
46
+ line?: number | undefined;
47
+ endLine?: number | undefined;
48
+ }>, "many">>;
49
+ hint: z.ZodOptional<z.ZodString>;
50
+ instructions: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
51
+ metrics: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
52
+ }, "strip", z.ZodTypeAny, {
53
+ id: string;
54
+ title: string;
55
+ details: string;
56
+ severity: "critical" | "high" | "medium" | "low" | "info";
57
+ gate: string;
58
+ files?: string[] | undefined;
59
+ hint?: string | undefined;
60
+ category?: string | undefined;
61
+ locations?: {
62
+ file: string;
63
+ line?: number | undefined;
64
+ endLine?: number | undefined;
65
+ }[] | undefined;
66
+ instructions?: string[] | undefined;
67
+ metrics?: Record<string, any> | undefined;
68
+ }, {
69
+ id: string;
70
+ title: string;
71
+ details: string;
72
+ gate: string;
73
+ severity?: "critical" | "high" | "medium" | "low" | "info" | undefined;
74
+ files?: string[] | undefined;
75
+ hint?: string | undefined;
76
+ category?: string | undefined;
77
+ locations?: {
78
+ file: string;
79
+ line?: number | undefined;
80
+ endLine?: number | undefined;
81
+ }[] | undefined;
82
+ instructions?: string[] | undefined;
83
+ metrics?: Record<string, any> | undefined;
84
+ }>;
6
85
  export declare const FixPacketV2Schema: z.ZodObject<{
7
- version: z.ZodLiteral<2>;
86
+ version: z.ZodLiteral<3>;
8
87
  goal: z.ZodDefault<z.ZodString>;
88
+ failed_gates: z.ZodArray<z.ZodString, "many">;
9
89
  violations: z.ZodArray<z.ZodObject<{
10
90
  id: z.ZodString;
11
91
  gate: z.ZodString;
@@ -14,6 +94,19 @@ export declare const FixPacketV2Schema: z.ZodObject<{
14
94
  title: z.ZodString;
15
95
  details: z.ZodString;
16
96
  files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
97
+ locations: z.ZodOptional<z.ZodArray<z.ZodObject<{
98
+ file: z.ZodString;
99
+ line: z.ZodOptional<z.ZodNumber>;
100
+ endLine: z.ZodOptional<z.ZodNumber>;
101
+ }, "strip", z.ZodTypeAny, {
102
+ file: string;
103
+ line?: number | undefined;
104
+ endLine?: number | undefined;
105
+ }, {
106
+ file: string;
107
+ line?: number | undefined;
108
+ endLine?: number | undefined;
109
+ }>, "many">>;
17
110
  hint: z.ZodOptional<z.ZodString>;
18
111
  instructions: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
19
112
  metrics: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
@@ -26,6 +119,11 @@ export declare const FixPacketV2Schema: z.ZodObject<{
26
119
  files?: string[] | undefined;
27
120
  hint?: string | undefined;
28
121
  category?: string | undefined;
122
+ locations?: {
123
+ file: string;
124
+ line?: number | undefined;
125
+ endLine?: number | undefined;
126
+ }[] | undefined;
29
127
  instructions?: string[] | undefined;
30
128
  metrics?: Record<string, any> | undefined;
31
129
  }, {
@@ -37,12 +135,43 @@ export declare const FixPacketV2Schema: z.ZodObject<{
37
135
  files?: string[] | undefined;
38
136
  hint?: string | undefined;
39
137
  category?: string | undefined;
138
+ locations?: {
139
+ file: string;
140
+ line?: number | undefined;
141
+ endLine?: number | undefined;
142
+ }[] | undefined;
40
143
  instructions?: string[] | undefined;
41
144
  metrics?: Record<string, any> | undefined;
42
145
  }>, "many">;
146
+ verification: z.ZodOptional<z.ZodObject<{
147
+ commands: z.ZodArray<z.ZodObject<{
148
+ cmd: z.ZodString;
149
+ purpose: z.ZodString;
150
+ }, "strip", z.ZodTypeAny, {
151
+ cmd: string;
152
+ purpose: string;
153
+ }, {
154
+ cmd: string;
155
+ purpose: string;
156
+ }>, "many">;
157
+ gate_command: z.ZodDefault<z.ZodString>;
158
+ }, "strip", z.ZodTypeAny, {
159
+ commands: {
160
+ cmd: string;
161
+ purpose: string;
162
+ }[];
163
+ gate_command: string;
164
+ }, {
165
+ commands: {
166
+ cmd: string;
167
+ purpose: string;
168
+ }[];
169
+ gate_command?: string | undefined;
170
+ }>>;
43
171
  constraints: z.ZodDefault<z.ZodOptional<z.ZodObject<{
44
172
  protected_paths: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
45
173
  do_not_touch: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
174
+ allowed_scope: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
46
175
  max_files_changed: z.ZodOptional<z.ZodNumber>;
47
176
  no_new_deps: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
48
177
  allowed_dependencies: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
@@ -52,19 +181,22 @@ export declare const FixPacketV2Schema: z.ZodObject<{
52
181
  protected_paths?: string[] | undefined;
53
182
  paradigm?: string | undefined;
54
183
  do_not_touch?: string[] | undefined;
184
+ allowed_scope?: string[] | undefined;
55
185
  max_files_changed?: number | undefined;
56
186
  allowed_dependencies?: string[] | undefined;
57
187
  }, {
58
188
  protected_paths?: string[] | undefined;
59
189
  paradigm?: string | undefined;
60
190
  do_not_touch?: string[] | undefined;
191
+ allowed_scope?: string[] | undefined;
61
192
  max_files_changed?: number | undefined;
62
193
  no_new_deps?: boolean | undefined;
63
194
  allowed_dependencies?: string[] | undefined;
64
195
  }>>>;
65
196
  }, "strip", z.ZodTypeAny, {
66
- version: 2;
197
+ version: 3;
67
198
  goal: string;
199
+ failed_gates: string[];
68
200
  violations: {
69
201
  id: string;
70
202
  title: string;
@@ -74,6 +206,11 @@ export declare const FixPacketV2Schema: z.ZodObject<{
74
206
  files?: string[] | undefined;
75
207
  hint?: string | undefined;
76
208
  category?: string | undefined;
209
+ locations?: {
210
+ file: string;
211
+ line?: number | undefined;
212
+ endLine?: number | undefined;
213
+ }[] | undefined;
77
214
  instructions?: string[] | undefined;
78
215
  metrics?: Record<string, any> | undefined;
79
216
  }[];
@@ -82,11 +219,20 @@ export declare const FixPacketV2Schema: z.ZodObject<{
82
219
  protected_paths?: string[] | undefined;
83
220
  paradigm?: string | undefined;
84
221
  do_not_touch?: string[] | undefined;
222
+ allowed_scope?: string[] | undefined;
85
223
  max_files_changed?: number | undefined;
86
224
  allowed_dependencies?: string[] | undefined;
87
225
  };
226
+ verification?: {
227
+ commands: {
228
+ cmd: string;
229
+ purpose: string;
230
+ }[];
231
+ gate_command: string;
232
+ } | undefined;
88
233
  }, {
89
- version: 2;
234
+ version: 3;
235
+ failed_gates: string[];
90
236
  violations: {
91
237
  id: string;
92
238
  title: string;
@@ -96,17 +242,33 @@ export declare const FixPacketV2Schema: z.ZodObject<{
96
242
  files?: string[] | undefined;
97
243
  hint?: string | undefined;
98
244
  category?: string | undefined;
245
+ locations?: {
246
+ file: string;
247
+ line?: number | undefined;
248
+ endLine?: number | undefined;
249
+ }[] | undefined;
99
250
  instructions?: string[] | undefined;
100
251
  metrics?: Record<string, any> | undefined;
101
252
  }[];
102
253
  goal?: string | undefined;
254
+ verification?: {
255
+ commands: {
256
+ cmd: string;
257
+ purpose: string;
258
+ }[];
259
+ gate_command?: string | undefined;
260
+ } | undefined;
103
261
  constraints?: {
104
262
  protected_paths?: string[] | undefined;
105
263
  paradigm?: string | undefined;
106
264
  do_not_touch?: string[] | undefined;
265
+ allowed_scope?: string[] | undefined;
107
266
  max_files_changed?: number | undefined;
108
267
  no_new_deps?: boolean | undefined;
109
268
  allowed_dependencies?: string[] | undefined;
110
269
  } | undefined;
111
270
  }>;
112
271
  export type FixPacketV2 = z.infer<typeof FixPacketV2Schema>;
272
+ export type Violation = z.infer<typeof ViolationSchema>;
273
+ export type ViolationLocation = z.infer<typeof ViolationLocationSchema>;
274
+ export {};
@@ -1,29 +1,55 @@
1
1
  import { z } from 'zod';
2
2
  /**
3
- * Fix Packet v2 Schema
4
- * Designed for high-fidelity communication with AI agents during the refinement loop.
3
+ * Fix Packet v3 Schema
4
+ *
5
+ * Designed for high-fidelity, machine-readable communication with AI agents.
6
+ * Every violation tells the agent exactly: who failed, which files, what rule,
7
+ * where in the file, and what must pass to verify the fix.
8
+ *
9
+ * v3 changes from v2:
10
+ * - Violations now include `location` (file + line range) for precise targeting
11
+ * - Top-level `verification` block: commands the agent MUST run after fixing
12
+ * - `allowed_scope`: explicit list of file globs the agent IS allowed to edit
13
+ * - `failed_gates`: summary list of gate IDs that failed (quick machine check)
5
14
  */
15
+ const ViolationLocationSchema = z.object({
16
+ file: z.string(),
17
+ line: z.number().optional(),
18
+ endLine: z.number().optional(),
19
+ });
20
+ const ViolationSchema = z.object({
21
+ id: z.string(), // Gate ID, e.g. "file-size"
22
+ gate: z.string(), // Same as id (kept for backwards compat)
23
+ severity: z.enum(['info', 'low', 'medium', 'high', 'critical']).default('medium'),
24
+ category: z.string().optional(), // Provenance: "traditional", "ai-drift", "security", etc.
25
+ title: z.string(),
26
+ details: z.string(),
27
+ files: z.array(z.string()).optional(),
28
+ locations: z.array(ViolationLocationSchema).optional(), // Precise file + line targets
29
+ hint: z.string().optional(),
30
+ instructions: z.array(z.string()).optional(),
31
+ metrics: z.record(z.any()).optional(), // e.g. { complexity: 15, threshold: 10 }
32
+ });
33
+ const VerificationSchema = z.object({
34
+ commands: z.array(z.object({
35
+ cmd: z.string(), // e.g. "npm run typecheck"
36
+ purpose: z.string(), // e.g. "Ensure no TypeScript errors"
37
+ })),
38
+ gate_command: z.string().default('rigour_check'), // The rigour tool to re-run
39
+ });
6
40
  export const FixPacketV2Schema = z.object({
7
- version: z.literal(2),
41
+ version: z.literal(3),
8
42
  goal: z.string().default('Achieve PASS state for all quality gates'),
9
- violations: z.array(z.object({
10
- id: z.string(),
11
- gate: z.string(),
12
- severity: z.enum(['info', 'low', 'medium', 'high', 'critical']).default('medium'),
13
- category: z.string().optional(),
14
- title: z.string(),
15
- details: z.string(),
16
- files: z.array(z.string()).optional(),
17
- hint: z.string().optional(),
18
- instructions: z.array(z.string()).optional(), // Step-by-step fix instructions
19
- metrics: z.record(z.any()).optional(), // e.g., { complexity: 15, max: 10 }
20
- })),
43
+ failed_gates: z.array(z.string()), // Quick list: ["file-size", "hallucinated-imports"]
44
+ violations: z.array(ViolationSchema),
45
+ verification: VerificationSchema.optional(),
21
46
  constraints: z.object({
22
47
  protected_paths: z.array(z.string()).optional(),
23
- do_not_touch: z.array(z.string()).optional(), // Alias for protected_paths
48
+ do_not_touch: z.array(z.string()).optional(),
49
+ allowed_scope: z.array(z.string()).optional(), // Globs the agent IS allowed to edit
24
50
  max_files_changed: z.number().optional(),
25
51
  no_new_deps: z.boolean().optional().default(true),
26
52
  allowed_dependencies: z.array(z.string()).optional(),
27
- paradigm: z.string().optional(), // 'oop', 'functional'
53
+ paradigm: z.string().optional(),
28
54
  }).optional().default({}),
29
55
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rigour-labs/core",
3
- "version": "4.3.4",
3
+ "version": "4.3.5",
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-darwin-arm64": "4.3.4",
63
- "@rigour-labs/brain-darwin-x64": "4.3.4",
64
- "@rigour-labs/brain-linux-x64": "4.3.4",
65
- "@rigour-labs/brain-linux-arm64": "4.3.4",
66
- "@rigour-labs/brain-win-x64": "4.3.4"
62
+ "@rigour-labs/brain-darwin-arm64": "4.3.5",
63
+ "@rigour-labs/brain-darwin-x64": "4.3.5",
64
+ "@rigour-labs/brain-win-x64": "4.3.5",
65
+ "@rigour-labs/brain-linux-x64": "4.3.5",
66
+ "@rigour-labs/brain-linux-arm64": "4.3.5"
67
67
  },
68
68
  "devDependencies": {
69
69
  "@types/better-sqlite3": "^7.6.12",