@rigour-labs/core 2.21.0 → 2.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/gates/runner.js +4 -4
- package/dist/gates/safety.d.ts +1 -1
- package/dist/gates/safety.js +3 -3
- package/dist/gates/security-patterns.js +1 -1
- package/dist/safety.test.js +6 -6
- package/dist/templates/index.js +1 -1
- package/dist/types/index.js +1 -1
- package/package.json +1 -1
- package/src/gates/runner.ts +4 -4
- package/src/gates/safety.ts +3 -3
- package/src/gates/security-patterns.ts +1 -1
- package/src/safety.test.ts +6 -6
- package/src/templates/index.ts +1 -1
- package/src/types/index.ts +1 -1
package/dist/gates/runner.js
CHANGED
|
@@ -2,7 +2,7 @@ import { FileGate } from './file.js';
|
|
|
2
2
|
import { ContentGate } from './content.js';
|
|
3
3
|
import { StructureGate } from './structure.js';
|
|
4
4
|
import { ASTGate } from './ast.js';
|
|
5
|
-
import {
|
|
5
|
+
import { FileGuardGate } from './safety.js';
|
|
6
6
|
import { DependencyGate } from './dependency.js';
|
|
7
7
|
import { CoverageGate } from './coverage.js';
|
|
8
8
|
import { ContextGate } from './context.js';
|
|
@@ -38,7 +38,7 @@ export class GateRunner {
|
|
|
38
38
|
}
|
|
39
39
|
this.gates.push(new ASTGate(this.config.gates));
|
|
40
40
|
this.gates.push(new DependencyGate(this.config));
|
|
41
|
-
this.gates.push(new
|
|
41
|
+
this.gates.push(new FileGuardGate(this.config.gates));
|
|
42
42
|
this.gates.push(new CoverageGate(this.config.gates));
|
|
43
43
|
if (this.config.gates.context?.enabled) {
|
|
44
44
|
this.gates.push(new ContextGate(this.config.gates));
|
|
@@ -51,8 +51,8 @@ export class GateRunner {
|
|
|
51
51
|
if (this.config.gates.checkpoint?.enabled) {
|
|
52
52
|
this.gates.push(new CheckpointGate(this.config.gates.checkpoint));
|
|
53
53
|
}
|
|
54
|
-
// Security Patterns Gate (code-level vulnerability detection)
|
|
55
|
-
if (this.config.gates.security?.enabled) {
|
|
54
|
+
// Security Patterns Gate (code-level vulnerability detection) — enabled by default since v2.15
|
|
55
|
+
if (this.config.gates.security?.enabled !== false) {
|
|
56
56
|
this.gates.push(new SecurityPatternsGate(this.config.gates.security));
|
|
57
57
|
}
|
|
58
58
|
// Environment Alignment Gate (Should be prioritized)
|
package/dist/gates/safety.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Gate, GateContext } from './base.js';
|
|
2
2
|
import { Failure, Gates } from '../types/index.js';
|
|
3
|
-
export declare class
|
|
3
|
+
export declare class FileGuardGate extends Gate {
|
|
4
4
|
private config;
|
|
5
5
|
constructor(config: Gates);
|
|
6
6
|
run(context: GateContext): Promise<Failure[]>;
|
package/dist/gates/safety.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Gate } from './base.js';
|
|
2
2
|
import { execa } from 'execa';
|
|
3
|
-
export class
|
|
3
|
+
export class FileGuardGate extends Gate {
|
|
4
4
|
config;
|
|
5
5
|
constructor(config) {
|
|
6
|
-
super('
|
|
6
|
+
super('file-guard', 'File Guard — Protected Paths');
|
|
7
7
|
this.config = config;
|
|
8
8
|
}
|
|
9
9
|
async run(context) {
|
|
@@ -14,7 +14,7 @@ export class SafetyGate extends Gate {
|
|
|
14
14
|
return [];
|
|
15
15
|
try {
|
|
16
16
|
// Check for modified files in protected paths using git
|
|
17
|
-
//
|
|
17
|
+
// File Guard - if an agent touched protected files, we fail.
|
|
18
18
|
const { stdout } = await execa('git', ['status', '--porcelain'], { cwd: context.cwd });
|
|
19
19
|
const modifiedFiles = stdout.split('\n')
|
|
20
20
|
.filter(line => {
|
|
@@ -138,7 +138,7 @@ export class SecurityPatternsGate extends Gate {
|
|
|
138
138
|
constructor(config = {}) {
|
|
139
139
|
super('security-patterns', 'Security Pattern Detection');
|
|
140
140
|
this.config = {
|
|
141
|
-
enabled: config.enabled ??
|
|
141
|
+
enabled: config.enabled ?? true,
|
|
142
142
|
sql_injection: config.sql_injection ?? true,
|
|
143
143
|
xss: config.xss ?? true,
|
|
144
144
|
path_traversal: config.path_traversal ?? true,
|
package/dist/safety.test.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import {
|
|
2
|
+
import { FileGuardGate } from './gates/safety.js';
|
|
3
3
|
import { execa } from 'execa';
|
|
4
4
|
vi.mock('execa');
|
|
5
|
-
describe('
|
|
5
|
+
describe('FileGuardGate', () => {
|
|
6
6
|
const config = {
|
|
7
7
|
safety: {
|
|
8
8
|
protected_paths: ['docs/'],
|
|
@@ -10,27 +10,27 @@ describe('SafetyGate', () => {
|
|
|
10
10
|
}
|
|
11
11
|
};
|
|
12
12
|
it('should flag modified (M) protected files', async () => {
|
|
13
|
-
const gate = new
|
|
13
|
+
const gate = new FileGuardGate(config);
|
|
14
14
|
vi.mocked(execa).mockResolvedValueOnce({ stdout: ' M docs/SPEC.md\n' });
|
|
15
15
|
const failures = await gate.run({ cwd: '/test', record: {} });
|
|
16
16
|
expect(failures).toHaveLength(1);
|
|
17
17
|
expect(failures[0].title).toContain("Protected file 'docs/SPEC.md' was modified.");
|
|
18
18
|
});
|
|
19
19
|
it('should flag added (A) protected files', async () => {
|
|
20
|
-
const gate = new
|
|
20
|
+
const gate = new FileGuardGate(config);
|
|
21
21
|
vi.mocked(execa).mockResolvedValueOnce({ stdout: 'A docs/NEW.md\n' });
|
|
22
22
|
const failures = await gate.run({ cwd: '/test', record: {} });
|
|
23
23
|
expect(failures).toHaveLength(1);
|
|
24
24
|
expect(failures[0].title).toContain("Protected file 'docs/NEW.md' was modified.");
|
|
25
25
|
});
|
|
26
26
|
it('should NOT flag untracked (??) protected files', async () => {
|
|
27
|
-
const gate = new
|
|
27
|
+
const gate = new FileGuardGate(config);
|
|
28
28
|
vi.mocked(execa).mockResolvedValueOnce({ stdout: '?? docs/UNTRAKED.md\n' });
|
|
29
29
|
const failures = await gate.run({ cwd: '/test', record: {} });
|
|
30
30
|
expect(failures).toHaveLength(0);
|
|
31
31
|
});
|
|
32
32
|
it('should correctly handle multiple mixed statuses', async () => {
|
|
33
|
-
const gate = new
|
|
33
|
+
const gate = new FileGuardGate(config);
|
|
34
34
|
vi.mocked(execa).mockResolvedValueOnce({
|
|
35
35
|
stdout: ' M docs/MODIFIED.md\n?? docs/NEW_UNTRACKED.md\n D docs/DELETED.md\n'
|
|
36
36
|
});
|
package/dist/templates/index.js
CHANGED
package/dist/types/index.js
CHANGED
|
@@ -86,7 +86,7 @@ export const GatesSchema = z.object({
|
|
|
86
86
|
auto_save_on_failure: z.boolean().optional().default(true),
|
|
87
87
|
}).optional().default({}),
|
|
88
88
|
security: z.object({
|
|
89
|
-
enabled: z.boolean().optional().default(
|
|
89
|
+
enabled: z.boolean().optional().default(true),
|
|
90
90
|
sql_injection: z.boolean().optional().default(true),
|
|
91
91
|
xss: z.boolean().optional().default(true),
|
|
92
92
|
path_traversal: z.boolean().optional().default(true),
|
package/package.json
CHANGED
package/src/gates/runner.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { FileGate } from './file.js';
|
|
|
4
4
|
import { ContentGate } from './content.js';
|
|
5
5
|
import { StructureGate } from './structure.js';
|
|
6
6
|
import { ASTGate } from './ast.js';
|
|
7
|
-
import {
|
|
7
|
+
import { FileGuardGate } from './safety.js';
|
|
8
8
|
import { DependencyGate } from './dependency.js';
|
|
9
9
|
import { CoverageGate } from './coverage.js';
|
|
10
10
|
import { ContextGate } from './context.js';
|
|
@@ -44,7 +44,7 @@ export class GateRunner {
|
|
|
44
44
|
}
|
|
45
45
|
this.gates.push(new ASTGate(this.config.gates));
|
|
46
46
|
this.gates.push(new DependencyGate(this.config));
|
|
47
|
-
this.gates.push(new
|
|
47
|
+
this.gates.push(new FileGuardGate(this.config.gates));
|
|
48
48
|
this.gates.push(new CoverageGate(this.config.gates));
|
|
49
49
|
|
|
50
50
|
if (this.config.gates.context?.enabled) {
|
|
@@ -61,8 +61,8 @@ export class GateRunner {
|
|
|
61
61
|
this.gates.push(new CheckpointGate(this.config.gates.checkpoint));
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
// Security Patterns Gate (code-level vulnerability detection)
|
|
65
|
-
if (this.config.gates.security?.enabled) {
|
|
64
|
+
// Security Patterns Gate (code-level vulnerability detection) — enabled by default since v2.15
|
|
65
|
+
if (this.config.gates.security?.enabled !== false) {
|
|
66
66
|
this.gates.push(new SecurityPatternsGate(this.config.gates.security));
|
|
67
67
|
}
|
|
68
68
|
|
package/src/gates/safety.ts
CHANGED
|
@@ -2,9 +2,9 @@ import { Gate, GateContext } from './base.js';
|
|
|
2
2
|
import { Failure, Gates } from '../types/index.js';
|
|
3
3
|
import { execa } from 'execa';
|
|
4
4
|
|
|
5
|
-
export class
|
|
5
|
+
export class FileGuardGate extends Gate {
|
|
6
6
|
constructor(private config: Gates) {
|
|
7
|
-
super('
|
|
7
|
+
super('file-guard', 'File Guard — Protected Paths');
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
async run(context: GateContext): Promise<Failure[]> {
|
|
@@ -16,7 +16,7 @@ export class SafetyGate extends Gate {
|
|
|
16
16
|
|
|
17
17
|
try {
|
|
18
18
|
// Check for modified files in protected paths using git
|
|
19
|
-
//
|
|
19
|
+
// File Guard - if an agent touched protected files, we fail.
|
|
20
20
|
const { stdout } = await execa('git', ['status', '--porcelain'], { cwd: context.cwd });
|
|
21
21
|
const modifiedFiles = stdout.split('\n')
|
|
22
22
|
.filter(line => {
|
|
@@ -171,7 +171,7 @@ export class SecurityPatternsGate extends Gate {
|
|
|
171
171
|
constructor(config: SecurityPatternsConfig = {}) {
|
|
172
172
|
super('security-patterns', 'Security Pattern Detection');
|
|
173
173
|
this.config = {
|
|
174
|
-
enabled: config.enabled ??
|
|
174
|
+
enabled: config.enabled ?? true,
|
|
175
175
|
sql_injection: config.sql_injection ?? true,
|
|
176
176
|
xss: config.xss ?? true,
|
|
177
177
|
path_traversal: config.path_traversal ?? true,
|
package/src/safety.test.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import {
|
|
2
|
+
import { FileGuardGate } from './gates/safety.js';
|
|
3
3
|
import { Gates } from './types/index.js';
|
|
4
4
|
import { execa } from 'execa';
|
|
5
5
|
|
|
6
6
|
vi.mock('execa');
|
|
7
7
|
|
|
8
|
-
describe('
|
|
8
|
+
describe('FileGuardGate', () => {
|
|
9
9
|
const config: Gates = {
|
|
10
10
|
safety: {
|
|
11
11
|
protected_paths: ['docs/'],
|
|
@@ -14,7 +14,7 @@ describe('SafetyGate', () => {
|
|
|
14
14
|
} as any;
|
|
15
15
|
|
|
16
16
|
it('should flag modified (M) protected files', async () => {
|
|
17
|
-
const gate = new
|
|
17
|
+
const gate = new FileGuardGate(config);
|
|
18
18
|
vi.mocked(execa).mockResolvedValueOnce({ stdout: ' M docs/SPEC.md\n' } as any);
|
|
19
19
|
|
|
20
20
|
const failures = await gate.run({ cwd: '/test', record: {} as any });
|
|
@@ -23,7 +23,7 @@ describe('SafetyGate', () => {
|
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
it('should flag added (A) protected files', async () => {
|
|
26
|
-
const gate = new
|
|
26
|
+
const gate = new FileGuardGate(config);
|
|
27
27
|
vi.mocked(execa).mockResolvedValueOnce({ stdout: 'A docs/NEW.md\n' } as any);
|
|
28
28
|
|
|
29
29
|
const failures = await gate.run({ cwd: '/test', record: {} as any });
|
|
@@ -32,7 +32,7 @@ describe('SafetyGate', () => {
|
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
it('should NOT flag untracked (??) protected files', async () => {
|
|
35
|
-
const gate = new
|
|
35
|
+
const gate = new FileGuardGate(config);
|
|
36
36
|
vi.mocked(execa).mockResolvedValueOnce({ stdout: '?? docs/UNTRAKED.md\n' } as any);
|
|
37
37
|
|
|
38
38
|
const failures = await gate.run({ cwd: '/test', record: {} as any });
|
|
@@ -40,7 +40,7 @@ describe('SafetyGate', () => {
|
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
it('should correctly handle multiple mixed statuses', async () => {
|
|
43
|
-
const gate = new
|
|
43
|
+
const gate = new FileGuardGate(config);
|
|
44
44
|
vi.mocked(execa).mockResolvedValueOnce({
|
|
45
45
|
stdout: ' M docs/MODIFIED.md\n?? docs/NEW_UNTRACKED.md\n D docs/DELETED.md\n'
|
|
46
46
|
} as any);
|
package/src/templates/index.ts
CHANGED
package/src/types/index.ts
CHANGED
|
@@ -87,7 +87,7 @@ export const GatesSchema = z.object({
|
|
|
87
87
|
auto_save_on_failure: z.boolean().optional().default(true),
|
|
88
88
|
}).optional().default({}),
|
|
89
89
|
security: z.object({
|
|
90
|
-
enabled: z.boolean().optional().default(
|
|
90
|
+
enabled: z.boolean().optional().default(true),
|
|
91
91
|
sql_injection: z.boolean().optional().default(true),
|
|
92
92
|
xss: z.boolean().optional().default(true),
|
|
93
93
|
path_traversal: z.boolean().optional().default(true),
|